diff -Nauprw linux-2.6.20/arch/arm/common/rtctime.c ../new/linux-2.6.20/arch/arm/common/rtctime.c --- linux-2.6.20/arch/arm/common/rtctime.c 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/arch/arm/common/rtctime.c 2007-11-21 11:51:41.000000000 +0530 @@ -201,13 +201,13 @@ static int rtc_ioctl(struct inode *inode } 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: diff -Nauprw linux-2.6.20/arch/arm/configs/ndk10_defconfig ../new/linux-2.6.20/arch/arm/configs/ndk10_defconfig --- linux-2.6.20/arch/arm/configs/ndk10_defconfig 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/arch/arm/configs/ndk10_defconfig 2007-11-21 11:51:41.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/arch/arm/configs/ndk15b06_defconfig ../new/linux-2.6.20/arch/arm/configs/ndk15b06_defconfig --- linux-2.6.20/arch/arm/configs/ndk15b06_defconfig 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/arch/arm/configs/ndk15b06_defconfig 2007-11-21 11:51:41.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/arch/arm/configs/ndk15_defconfig ../new/linux-2.6.20/arch/arm/configs/ndk15_defconfig --- linux-2.6.20/arch/arm/configs/ndk15_defconfig 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/arch/arm/configs/ndk15_defconfig 2007-11-21 11:51:41.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/arch/arm/configs/nhk15_defconfig ../new/linux-2.6.20/arch/arm/configs/nhk15_defconfig --- linux-2.6.20/arch/arm/configs/nhk15_defconfig 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/arch/arm/configs/nhk15_defconfig 2008-11-19 16:47:02.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/arch/arm/Kconfig ../new/linux-2.6.20/arch/arm/Kconfig --- linux-2.6.20/arch/arm/Kconfig 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/arch/arm/Kconfig 2007-11-21 11:51:41.000000000 +0530 @@ -119,7 +119,7 @@ menu "System Type" choice prompt "ARM system type" - default ARCH_VERSATILE + default ARCH_NOMADIK config ARCH_AAEC2000 bool "Agilent AAEC-2000 based" @@ -203,6 +203,14 @@ config ARCH_NETX 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 @@ -381,6 +389,7 @@ 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 @@ -740,7 +749,7 @@ config XIP_PHYS_ADDR 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" @@ -776,6 +785,17 @@ config CPU_FREQ_IMX 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 @@ -910,6 +930,7 @@ if PCMCIA || ARCH_CLPS7500 || ARCH_IOP32 source "drivers/ide/Kconfig" endif + source "drivers/scsi/Kconfig" source "drivers/ata/Kconfig" diff -Nauprw linux-2.6.20/arch/arm/kernel/armksyms.c ../new/linux-2.6.20/arch/arm/kernel/armksyms.c --- linux-2.6.20/arch/arm/kernel/armksyms.c 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/arch/arm/kernel/armksyms.c 2007-11-21 11:51:41.000000000 +0530 @@ -31,6 +31,13 @@ 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); @@ -139,6 +146,13 @@ 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); diff -Nauprw linux-2.6.20/arch/arm/kernel/dma.c ../new/linux-2.6.20/arch/arm/kernel/dma.c --- linux-2.6.20/arch/arm/kernel/dma.c 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/arch/arm/kernel/dma.c 2007-11-21 11:51:41.000000000 +0530 @@ -228,6 +228,7 @@ 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) { diff -Nauprw linux-2.6.20/arch/arm/kernel/entry-armv.S ../new/linux-2.6.20/arch/arm/kernel/entry-armv.S --- linux-2.6.20/arch/arm/kernel/entry-armv.S 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/arch/arm/kernel/entry-armv.S 2007-11-21 11:51:41.000000000 +0530 @@ -15,6 +15,7 @@ * it to save wrong values... Be aware! */ +#include #include #include #include @@ -239,6 +240,7 @@ svc_preempt: beq preempt_return @ go again b 1b #endif + CFI_END_FRAME(__irq_svc) .align 5 __und_svc: diff -Nauprw linux-2.6.20/arch/arm/kernel/irq.c ../new/linux-2.6.20/arch/arm/kernel/irq.c --- linux-2.6.20/arch/arm/kernel/irq.c 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/arch/arm/kernel/irq.c 2007-11-21 11:51:41.000000000 +0530 @@ -76,7 +76,19 @@ int show_interrupts(struct seq_file *p, 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) diff -Nauprw linux-2.6.20/arch/arm/kernel/kgdb.c ../new/linux-2.6.20/arch/arm/kernel/kgdb.c --- linux-2.6.20/arch/arm/kernel/kgdb.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/arch/arm/kernel/kgdb.c 2008-10-20 13:37:44.000000000 +0530 @@ -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 +}; diff -Nauprw linux-2.6.20/arch/arm/kernel/kgdb-jmp.S ../new/linux-2.6.20/arch/arm/kernel/kgdb-jmp.S --- linux-2.6.20/arch/arm/kernel/kgdb-jmp.S 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/arch/arm/kernel/kgdb-jmp.S 2007-11-21 11:51:41.000000000 +0530 @@ -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}^ diff -Nauprw linux-2.6.20/arch/arm/kernel/Makefile ../new/linux-2.6.20/arch/arm/kernel/Makefile --- linux-2.6.20/arch/arm/kernel/Makefile 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/arch/arm/kernel/Makefile 2007-11-21 11:51:41.000000000 +0530 @@ -19,6 +19,7 @@ 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 diff -Nauprw linux-2.6.20/arch/arm/kernel/setup.c ../new/linux-2.6.20/arch/arm/kernel/setup.c --- linux-2.6.20/arch/arm/kernel/setup.c 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/arch/arm/kernel/setup.c 2007-11-21 11:51:41.000000000 +0530 @@ -829,6 +829,11 @@ void __init setup_arch(char **cmdline_p) conswitchp = &dummy_con; #endif #endif + +#if defined(CONFIG_KGDB) + extern void __init early_trap_init(void); + early_trap_init(); +#endif } diff -Nauprw linux-2.6.20/arch/arm/kernel/traps.c ../new/linux-2.6.20/arch/arm/kernel/traps.c --- linux-2.6.20/arch/arm/kernel/traps.c 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/arch/arm/kernel/traps.c 2007-11-21 11:51:41.000000000 +0530 @@ -279,6 +279,7 @@ asmlinkage void do_undefinstr(struct pt_ unsigned int instr; struct undef_hook *hook; siginfo_t info; + mm_segment_t fs; void __user *pc; /* @@ -288,12 +289,15 @@ asmlinkage void do_undefinstr(struct pt_ */ 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) { @@ -682,6 +686,13 @@ 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[]; diff -Nauprw linux-2.6.20/arch/arm/lib/gcclib.h ../new/linux-2.6.20/arch/arm/lib/gcclib.h --- linux-2.6.20/arch/arm/lib/gcclib.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/arch/arm/lib/gcclib.h 2007-11-21 11:51:41.000000000 +0530 @@ -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; + diff -Nauprw linux-2.6.20/arch/arm/lib/longlong.h ../new/linux-2.6.20/arch/arm/lib/longlong.h --- linux-2.6.20/arch/arm/lib/longlong.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/arch/arm/lib/longlong.h 2007-11-21 11:51:41.000000000 +0530 @@ -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) diff -Nauprw linux-2.6.20/arch/arm/lib/Makefile ../new/linux-2.6.20/arch/arm/lib/Makefile --- linux-2.6.20/arch/arm/lib/Makefile 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/arch/arm/lib/Makefile 2007-11-21 11:51:41.000000000 +0530 @@ -13,7 +13,7 @@ lib-y := backtrace.o changebit.o csumip 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 diff -Nauprw linux-2.6.20/arch/arm/lib/udivdi3.c ../new/linux-2.6.20/arch/arm/lib/udivdi3.c --- linux-2.6.20/arch/arm/lib/udivdi3.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/arch/arm/lib/udivdi3.c 2007-11-21 11:51:41.000000000 +0530 @@ -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; +} + diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/clock.c ../new/linux-2.6.20/arch/arm/mach-nomadik/clock.c --- linux-2.6.20/arch/arm/mach-nomadik/clock.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/arch/arm/mach-nomadik/clock.c 2007-11-21 11:51:41.000000000 +0530 @@ -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); diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/clock.h ../new/linux-2.6.20/arch/arm/mach-nomadik/clock.h --- linux-2.6.20/arch/arm/mach-nomadik/clock.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/arch/arm/mach-nomadik/clock.h 2007-11-21 11:51:41.000000000 +0530 @@ -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); diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/cpu.c ../new/linux-2.6.20/arch/arm/mach-nomadik/cpu.c --- linux-2.6.20/arch/arm/mach-nomadik/cpu.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/arch/arm/mach-nomadik/cpu.c 2008-07-04 23:45:03.000000000 +0530 @@ -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); diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/create_kconfig.pl ../new/linux-2.6.20/arch/arm/mach-nomadik/create_kconfig.pl --- linux-2.6.20/arch/arm/mach-nomadik/create_kconfig.pl 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/arch/arm/mach-nomadik/create_kconfig.pl 2007-11-21 11:51:41.000000000 +0530 @@ -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; + diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/deep_sleep.S ../new/linux-2.6.20/arch/arm/mach-nomadik/deep_sleep.S --- linux-2.6.20/arch/arm/mach-nomadik/deep_sleep.S 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/arch/arm/mach-nomadik/deep_sleep.S 2008-10-20 13:37:44.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/dfs.S ../new/linux-2.6.20/arch/arm/mach-nomadik/dfs.S --- linux-2.6.20/arch/arm/mach-nomadik/dfs.S 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/arch/arm/mach-nomadik/dfs.S 2008-07-28 15:20:41.000000000 +0530 @@ -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 + + + + diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/dma.c ../new/linux-2.6.20/arch/arm/mach-nomadik/dma.c --- linux-2.6.20/arch/arm/mach-nomadik/dma.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/arch/arm/mach-nomadik/dma.c 2008-07-04 23:45:04.000000000 +0530 @@ -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"); diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/fsmc.c ../new/linux-2.6.20/arch/arm/mach-nomadik/fsmc.c --- linux-2.6.20/arch/arm/mach-nomadik/fsmc.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/arch/arm/mach-nomadik/fsmc.c 2007-11-21 11:51:41.000000000 +0530 @@ -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"); diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/gpio.c ../new/linux-2.6.20/arch/arm/mach-nomadik/gpio.c --- linux-2.6.20/arch/arm/mach-nomadik/gpio.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/arch/arm/mach-nomadik/gpio.c 2008-09-16 23:41:14.000000000 +0530 @@ -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"); diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/irq.c ../new/linux-2.6.20/arch/arm/mach-nomadik/irq.c --- linux-2.6.20/arch/arm/mach-nomadik/irq.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/arch/arm/mach-nomadik/irq.c 2007-11-21 11:51:41.000000000 +0530 @@ -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")"); +} diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/Kconfig-nomadik ../new/linux-2.6.20/arch/arm/mach-nomadik/Kconfig-nomadik --- linux-2.6.20/arch/arm/mach-nomadik/Kconfig-nomadik 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/arch/arm/mach-nomadik/Kconfig-nomadik 2008-07-17 16:42:38.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/l2cc.c ../new/linux-2.6.20/arch/arm/mach-nomadik/l2cc.c --- linux-2.6.20/arch/arm/mach-nomadik/l2cc.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/arch/arm/mach-nomadik/l2cc.c 2008-07-04 23:45:55.000000000 +0530 @@ -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); diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/Makefile ../new/linux-2.6.20/arch/arm/mach-nomadik/Makefile --- linux-2.6.20/arch/arm/mach-nomadik/Makefile 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/arch/arm/mach-nomadik/Makefile 2008-07-04 23:45:06.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/Makefile.boot ../new/linux-2.6.20/arch/arm/mach-nomadik/Makefile.boot --- linux-2.6.20/arch/arm/mach-nomadik/Makefile.boot 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/arch/arm/mach-nomadik/Makefile.boot 2007-11-21 11:51:41.000000000 +0530 @@ -0,0 +1,4 @@ + zreladdr-y := 0x00008000 +params_phys-y := 0x00000100 +initrd_phys-y := 0x00800000 + diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/msp.c ../new/linux-2.6.20/arch/arm/mach-nomadik/msp.c --- linux-2.6.20/arch/arm/mach-nomadik/msp.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/arch/arm/mach-nomadik/msp.c 2008-11-19 16:47:02.000000000 +0530 @@ -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"); diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/msp.h ../new/linux-2.6.20/arch/arm/mach-nomadik/msp.h --- linux-2.6.20/arch/arm/mach-nomadik/msp.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/arch/arm/mach-nomadik/msp.h 2007-11-21 11:51:41.000000000 +0530 @@ -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 + diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/mtu.c ../new/linux-2.6.20/arch/arm/mach-nomadik/mtu.c --- linux-2.6.20/arch/arm/mach-nomadik/mtu.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/arch/arm/mach-nomadik/mtu.c 2007-11-21 11:51:41.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ndk10_cut_a1_Kconfig ../new/linux-2.6.20/arch/arm/mach-nomadik/ndk10_cut_a1_Kconfig --- linux-2.6.20/arch/arm/mach-nomadik/ndk10_cut_a1_Kconfig 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/arch/arm/mach-nomadik/ndk10_cut_a1_Kconfig 2007-11-21 11:51:41.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ndk10_cut_b06_Kconfig ../new/linux-2.6.20/arch/arm/mach-nomadik/ndk10_cut_b06_Kconfig --- linux-2.6.20/arch/arm/mach-nomadik/ndk10_cut_b06_Kconfig 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/arch/arm/mach-nomadik/ndk10_cut_b06_Kconfig 2007-11-21 11:51:41.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ndk10_cut_b0_Kconfig ../new/linux-2.6.20/arch/arm/mach-nomadik/ndk10_cut_b0_Kconfig --- linux-2.6.20/arch/arm/mach-nomadik/ndk10_cut_b0_Kconfig 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/arch/arm/mach-nomadik/ndk10_cut_b0_Kconfig 2007-11-21 11:51:41.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ndk10_devices.c ../new/linux-2.6.20/arch/arm/mach-nomadik/ndk10_devices.c --- linux-2.6.20/arch/arm/mach-nomadik/ndk10_devices.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/arch/arm/mach-nomadik/ndk10_devices.c 2007-11-21 11:51:41.000000000 +0530 @@ -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(); +} + + diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ndk15c02_devices.c ../new/linux-2.6.20/arch/arm/mach-nomadik/ndk15c02_devices.c --- linux-2.6.20/arch/arm/mach-nomadik/ndk15c02_devices.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/arch/arm/mach-nomadik/ndk15c02_devices.c 2007-11-21 11:51:41.000000000 +0530 @@ -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)); +} diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ndk15_devices.c ../new/linux-2.6.20/arch/arm/mach-nomadik/ndk15_devices.c --- linux-2.6.20/arch/arm/mach-nomadik/ndk15_devices.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/arch/arm/mach-nomadik/ndk15_devices.c 2008-09-17 13:23:32.000000000 +0530 @@ -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); +} diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ndk15_rev2_b_03_Kconfig ../new/linux-2.6.20/arch/arm/mach-nomadik/ndk15_rev2_b_03_Kconfig --- linux-2.6.20/arch/arm/mach-nomadik/ndk15_rev2_b_03_Kconfig 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/arch/arm/mach-nomadik/ndk15_rev2_b_03_Kconfig 2007-11-21 11:51:41.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ndk15_rev2_b_05_Kconfig ../new/linux-2.6.20/arch/arm/mach-nomadik/ndk15_rev2_b_05_Kconfig --- linux-2.6.20/arch/arm/mach-nomadik/ndk15_rev2_b_05_Kconfig 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/arch/arm/mach-nomadik/ndk15_rev2_b_05_Kconfig 2007-11-21 11:51:41.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ndk15_rev2_b_06_Kconfig ../new/linux-2.6.20/arch/arm/mach-nomadik/ndk15_rev2_b_06_Kconfig --- linux-2.6.20/arch/arm/mach-nomadik/ndk15_rev2_b_06_Kconfig 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/arch/arm/mach-nomadik/ndk15_rev2_b_06_Kconfig 2007-11-21 11:51:41.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ndk15_rev3_c_02_Kconfig ../new/linux-2.6.20/arch/arm/mach-nomadik/ndk15_rev3_c_02_Kconfig --- linux-2.6.20/arch/arm/mach-nomadik/ndk15_rev3_c_02_Kconfig 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/arch/arm/mach-nomadik/ndk15_rev3_c_02_Kconfig 2007-11-21 11:51:41.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/nhk15_devices.c ../new/linux-2.6.20/arch/arm/mach-nomadik/nhk15_devices.c --- linux-2.6.20/arch/arm/mach-nomadik/nhk15_devices.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/arch/arm/mach-nomadik/nhk15_devices.c 2008-09-17 13:23:32.000000000 +0530 @@ -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)); +} diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/nhk15_Kconfig ../new/linux-2.6.20/arch/arm/mach-nomadik/nhk15_Kconfig --- linux-2.6.20/arch/arm/mach-nomadik/nhk15_Kconfig 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/arch/arm/mach-nomadik/nhk15_Kconfig 2007-11-21 11:51:41.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/normal.S ../new/linux-2.6.20/arch/arm/mach-nomadik/normal.S --- linux-2.6.20/arch/arm/mach-nomadik/normal.S 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/arch/arm/mach-nomadik/normal.S 2008-07-28 15:20:42.000000000 +0530 @@ -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} + + diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/pm.c ../new/linux-2.6.20/arch/arm/mach-nomadik/pm.c --- linux-2.6.20/arch/arm/mach-nomadik/pm.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/arch/arm/mach-nomadik/pm.c 2007-11-21 11:51:41.000000000 +0530 @@ -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); diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/power.c ../new/linux-2.6.20/arch/arm/mach-nomadik/power.c --- linux-2.6.20/arch/arm/mach-nomadik/power.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/arch/arm/mach-nomadik/power.c 2008-11-19 16:47:03.000000000 +0530 @@ -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"); diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/sleep.c ../new/linux-2.6.20/arch/arm/mach-nomadik/sleep.c --- linux-2.6.20/arch/arm/mach-nomadik/sleep.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/arch/arm/mach-nomadik/sleep.c 2008-08-21 18:04:17.000000000 +0530 @@ -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; +} diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/slow.S ../new/linux-2.6.20/arch/arm/mach-nomadik/slow.S --- linux-2.6.20/arch/arm/mach-nomadik/slow.S 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/arch/arm/mach-nomadik/slow.S 2008-07-28 15:20:45.000000000 +0530 @@ -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} + + diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/soft_sleep.S ../new/linux-2.6.20/arch/arm/mach-nomadik/soft_sleep.S --- linux-2.6.20/arch/arm/mach-nomadik/soft_sleep.S 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/arch/arm/mach-nomadik/soft_sleep.S 2008-07-28 15:20:47.000000000 +0530 @@ -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} + + diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ssp.c ../new/linux-2.6.20/arch/arm/mach-nomadik/ssp.c --- linux-2.6.20/arch/arm/mach-nomadik/ssp.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/arch/arm/mach-nomadik/ssp.c 2008-07-04 23:45:10.000000000 +0530 @@ -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"); diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/stn8810_devices.c ../new/linux-2.6.20/arch/arm/mach-nomadik/stn8810_devices.c --- linux-2.6.20/arch/arm/mach-nomadik/stn8810_devices.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/arch/arm/mach-nomadik/stn8810_devices.c 2007-11-21 11:51:41.000000000 +0530 @@ -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 + diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/stn8815_devices.c ../new/linux-2.6.20/arch/arm/mach-nomadik/stn8815_devices.c --- linux-2.6.20/arch/arm/mach-nomadik/stn8815_devices.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/arch/arm/mach-nomadik/stn8815_devices.c 2008-11-19 16:47:03.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/timer.c ../new/linux-2.6.20/arch/arm/mach-nomadik/timer.c --- linux-2.6.20/arch/arm/mach-nomadik/timer.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/arch/arm/mach-nomadik/timer.c 2008-07-04 23:45:12.000000000 +0530 @@ -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 +}; diff -Nauprw linux-2.6.20/arch/arm/Makefile ../new/linux-2.6.20/arch/arm/Makefile --- linux-2.6.20/arch/arm/Makefile 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/arch/arm/Makefile 2007-11-21 11:51:41.000000000 +0530 @@ -20,7 +20,7 @@ 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),) @@ -89,6 +89,7 @@ CHECKFLAGS += -D__arm__ 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 @@ -106,6 +107,7 @@ 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 @@ -200,12 +202,21 @@ else 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 @@ -218,8 +229,23 @@ zinstall install: vmlinux 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) diff -Nauprw linux-2.6.20/arch/arm/mm/extable.c ../new/linux-2.6.20/arch/arm/mm/extable.c --- linux-2.6.20/arch/arm/mm/extable.c 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/arch/arm/mm/extable.c 2007-11-21 11:51:41.000000000 +0530 @@ -2,6 +2,7 @@ * linux/arch/arm/mm/extable.c */ #include +#include #include int fixup_exception(struct pt_regs *regs) @@ -11,6 +12,12 @@ int fixup_exception(struct pt_regs *regs 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; } diff -Nauprw linux-2.6.20/arch/arm/mm/init.c ../new/linux-2.6.20/arch/arm/mm/init.c --- linux-2.6.20/arch/arm/mm/init.c 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/arch/arm/mm/init.c 2007-11-21 11:51:41.000000000 +0530 @@ -89,7 +89,6 @@ void show_mem(void) 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 diff -Nauprw linux-2.6.20/arch/arm/mm/Kconfig ../new/linux-2.6.20/arch/arm/mm/Kconfig --- linux-2.6.20/arch/arm/mm/Kconfig 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/arch/arm/mm/Kconfig 2007-11-21 11:51:41.000000000 +0530 @@ -60,7 +60,7 @@ config CPU_ARM710 # 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 @@ -109,7 +109,7 @@ config CPU_ARM9TDMI # 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 @@ -131,7 +131,7 @@ config CPU_ARM920T # 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 @@ -168,10 +168,15 @@ config CPU_ARM925T 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 @@ -223,7 +228,7 @@ config CPU_ARM946E # 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 @@ -241,7 +246,7 @@ config CPU_ARM1020 # 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 @@ -254,7 +259,7 @@ config CPU_ARM1020E # 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 @@ -272,7 +277,7 @@ config CPU_ARM1022 # 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 @@ -345,7 +350,7 @@ config CPU_XSC3 # 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 diff -Nauprw linux-2.6.20/arch/arm/mm/proc-arm926.S ../new/linux-2.6.20/arch/arm/mm/proc-arm926.S --- linux-2.6.20/arch/arm/mm/proc-arm926.S 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/arch/arm/mm/proc-arm926.S 2008-10-20 13:37:44.000000000 +0530 @@ -24,6 +24,10 @@ * 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 @@ -33,6 +37,7 @@ #include #include #include +#include #include "proc-macros.S" /* @@ -65,9 +70,15 @@ ENTRY(cpu_arm926_proc_fin) 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} @@ -253,6 +264,9 @@ ENTRY(arm926_dma_inv_range) 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 @@ -274,6 +288,9 @@ ENTRY(arm926_dma_clean_range) 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 @@ -296,6 +313,9 @@ ENTRY(arm926_dma_flush_range) 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 @@ -341,6 +361,10 @@ ENTRY(cpu_arm926_switch_mm) 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 @@ -411,6 +435,12 @@ __arm926_setup: #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 diff -Nauprw linux-2.6.20/arch/arm/oprofile/common.c ../new/linux-2.6.20/arch/arm/oprofile/common.c --- linux-2.6.20/arch/arm/oprofile/common.c 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/arch/arm/oprofile/common.c 2008-09-17 13:23:32.000000000 +0530 @@ -153,10 +153,11 @@ int __init oprofile_arch_init(struct opr 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; } diff -Nauprw linux-2.6.20/Documentation/arm/STM-Nomadik/debug_strategy.txt ../new/linux-2.6.20/Documentation/arm/STM-Nomadik/debug_strategy.txt --- linux-2.6.20/Documentation/arm/STM-Nomadik/debug_strategy.txt 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/Documentation/arm/STM-Nomadik/debug_strategy.txt 2007-11-21 11:51:41.000000000 +0530 @@ -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. + * + */ + + diff -Nauprw linux-2.6.20/Documentation/arm/STM-Nomadik/dma_user_guide.txt ../new/linux-2.6.20/Documentation/arm/STM-Nomadik/dma_user_guide.txt --- linux-2.6.20/Documentation/arm/STM-Nomadik/dma_user_guide.txt 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/Documentation/arm/STM-Nomadik/dma_user_guide.txt 2007-11-21 11:51:41.000000000 +0530 @@ -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. + +============================================================================== + + diff -Nauprw linux-2.6.20/Documentation/arm/STM-Nomadik/faqs.txt ../new/linux-2.6.20/Documentation/arm/STM-Nomadik/faqs.txt --- linux-2.6.20/Documentation/arm/STM-Nomadik/faqs.txt 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/Documentation/arm/STM-Nomadik/faqs.txt 2007-11-21 11:51:41.000000000 +0530 @@ -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 + +============================================================================== + + diff -Nauprw linux-2.6.20/Documentation/arm/STM-Nomadik/gpio_user_guide.txt ../new/linux-2.6.20/Documentation/arm/STM-Nomadik/gpio_user_guide.txt --- linux-2.6.20/Documentation/arm/STM-Nomadik/gpio_user_guide.txt 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/Documentation/arm/STM-Nomadik/gpio_user_guide.txt 2007-11-21 11:51:41.000000000 +0530 @@ -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 + +======================================================================================= + diff -Nauprw linux-2.6.20/Documentation/arm/STM-Nomadik/HOWTO-add_newboard.txt ../new/linux-2.6.20/Documentation/arm/STM-Nomadik/HOWTO-add_newboard.txt --- linux-2.6.20/Documentation/arm/STM-Nomadik/HOWTO-add_newboard.txt 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/Documentation/arm/STM-Nomadik/HOWTO-add_newboard.txt 2007-11-21 11:51:41.000000000 +0530 @@ -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 +=============================================================================== + diff -Nauprw linux-2.6.20/Documentation/arm/STM-Nomadik/HOWTO-nfsboot.txt ../new/linux-2.6.20/Documentation/arm/STM-Nomadik/HOWTO-nfsboot.txt --- linux-2.6.20/Documentation/arm/STM-Nomadik/HOWTO-nfsboot.txt 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/Documentation/arm/STM-Nomadik/HOWTO-nfsboot.txt 2007-11-21 11:51:41.000000000 +0530 @@ -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 + diff -Nauprw linux-2.6.20/Documentation/arm/STM-Nomadik/irq_usrguide.txt ../new/linux-2.6.20/Documentation/arm/STM-Nomadik/irq_usrguide.txt --- linux-2.6.20/Documentation/arm/STM-Nomadik/irq_usrguide.txt 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/Documentation/arm/STM-Nomadik/irq_usrguide.txt 2007-11-21 11:51:41.000000000 +0530 @@ -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. + +=============================================================================== + diff -Nauprw linux-2.6.20/Documentation/arm/STM-Nomadik/power_management.txt ../new/linux-2.6.20/Documentation/arm/STM-Nomadik/power_management.txt --- linux-2.6.20/Documentation/arm/STM-Nomadik/power_management.txt 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/Documentation/arm/STM-Nomadik/power_management.txt 2007-11-21 11:51:41.000000000 +0530 @@ -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 + * + * + * + */ + + diff -Nauprw linux-2.6.20/Documentation/DocBook/kgdb.tmpl ../new/linux-2.6.20/Documentation/DocBook/kgdb.tmpl --- linux-2.6.20/Documentation/DocBook/kgdb.tmpl 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/Documentation/DocBook/kgdb.tmpl 2007-11-21 11:51:41.000000000 +0530 @@ -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 + +
diff -Nauprw linux-2.6.20/Documentation/DocBook/Makefile ../new/linux-2.6.20/Documentation/DocBook/Makefile --- linux-2.6.20/Documentation/DocBook/Makefile 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/Documentation/DocBook/Makefile 2007-11-21 11:51:41.000000000 +0530 @@ -11,7 +11,8 @@ DOCBOOKS := wanbook.xml z8530book.xml mc 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): diff -Nauprw linux-2.6.20/drivers/char/keyboard.c ../new/linux-2.6.20/drivers/char/keyboard.c --- linux-2.6.20/drivers/char/keyboard.c 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/drivers/char/keyboard.c 2007-11-21 11:51:41.000000000 +0530 @@ -1183,6 +1183,7 @@ static void kbd_keycode(unsigned int key 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 diff -Nauprw linux-2.6.20/drivers/cpufreq/Kconfig ../new/linux-2.6.20/drivers/cpufreq/Kconfig --- linux-2.6.20/drivers/cpufreq/Kconfig 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/drivers/cpufreq/Kconfig 2007-11-21 11:51:41.000000000 +0530 @@ -140,4 +140,8 @@ config CPU_FREQ_GOV_CONSERVATIVE If in doubt, say N. +config CPU_FREQ_NOMADIK + tristate "cpu freq scaling support for nomadik" + depends on CPU_FREQ + endif # CPU_FREQ diff -Nauprw linux-2.6.20/drivers/hwmon/Kconfig ../new/linux-2.6.20/drivers/hwmon/Kconfig --- linux-2.6.20/drivers/hwmon/Kconfig 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/drivers/hwmon/Kconfig 2008-09-16 23:41:15.000000000 +0530 @@ -230,6 +230,19 @@ config SENSORS_IT87 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 diff -Nauprw linux-2.6.20/drivers/hwmon/lis3lv02dl.c ../new/linux-2.6.20/drivers/hwmon/lis3lv02dl.c --- linux-2.6.20/drivers/hwmon/lis3lv02dl.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/hwmon/lis3lv02dl.c 2008-09-16 23:41:59.000000000 +0530 @@ -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); diff -Nauprw linux-2.6.20/drivers/hwmon/Makefile ../new/linux-2.6.20/drivers/hwmon/Makefile --- linux-2.6.20/drivers/hwmon/Makefile 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/drivers/hwmon/Makefile 2008-09-16 23:41:15.000000000 +0530 @@ -30,6 +30,7 @@ obj-$(CONFIG_SENSORS_GL520SM) += gl520sm 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 diff -Nauprw linux-2.6.20/drivers/i2c/busses/i2c-nomadik.c ../new/linux-2.6.20/drivers/i2c/busses/i2c-nomadik.c --- linux-2.6.20/drivers/i2c/busses/i2c-nomadik.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/i2c/busses/i2c-nomadik.c 2008-10-20 13:37:45.000000000 +0530 @@ -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"); diff -Nauprw linux-2.6.20/drivers/i2c/busses/i2c-nomadik.h ../new/linux-2.6.20/drivers/i2c/busses/i2c-nomadik.h --- linux-2.6.20/drivers/i2c/busses/i2c-nomadik.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/i2c/busses/i2c-nomadik.h 2008-07-04 23:45:14.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/drivers/i2c/busses/i2c-stn8810.c ../new/linux-2.6.20/drivers/i2c/busses/i2c-stn8810.c --- linux-2.6.20/drivers/i2c/busses/i2c-stn8810.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/i2c/busses/i2c-stn8810.c 2008-07-04 23:45:14.000000000 +0530 @@ -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); +} + + diff -Nauprw linux-2.6.20/drivers/i2c/busses/i2c-stn8815.c ../new/linux-2.6.20/drivers/i2c/busses/i2c-stn8815.c --- linux-2.6.20/drivers/i2c/busses/i2c-stn8815.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/i2c/busses/i2c-stn8815.c 2008-07-04 23:45:16.000000000 +0530 @@ -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) +{ +} + + diff -Nauprw linux-2.6.20/drivers/i2c/busses/Kconfig ../new/linux-2.6.20/drivers/i2c/busses/Kconfig --- linux-2.6.20/drivers/i2c/busses/Kconfig 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/drivers/i2c/busses/Kconfig 2007-11-21 11:51:41.000000000 +0530 @@ -17,6 +17,16 @@ config I2C_ALI1535 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 diff -Nauprw linux-2.6.20/drivers/i2c/busses/Makefile ../new/linux-2.6.20/drivers/i2c/busses/Makefile --- linux-2.6.20/drivers/i2c/busses/Makefile 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/drivers/i2c/busses/Makefile 2007-11-21 11:51:41.000000000 +0530 @@ -2,6 +2,23 @@ # 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 @@ -50,3 +67,8 @@ 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 + + diff -Nauprw linux-2.6.20/drivers/i2c/chips/epio-nomadik.c ../new/linux-2.6.20/drivers/i2c/chips/epio-nomadik.c --- linux-2.6.20/drivers/i2c/chips/epio-nomadik.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/i2c/chips/epio-nomadik.c 2008-07-04 23:45:17.000000000 +0530 @@ -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"); + + diff -Nauprw linux-2.6.20/drivers/i2c/chips/Kconfig ../new/linux-2.6.20/drivers/i2c/chips/Kconfig --- linux-2.6.20/drivers/i2c/chips/Kconfig 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/drivers/i2c/chips/Kconfig 2007-11-21 11:51:41.000000000 +0530 @@ -125,4 +125,13 @@ config SENSORS_MAX6875 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 diff -Nauprw linux-2.6.20/drivers/i2c/chips/Makefile ../new/linux-2.6.20/drivers/i2c/chips/Makefile --- linux-2.6.20/drivers/i2c/chips/Makefile 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/drivers/i2c/chips/Makefile 2007-11-21 11:51:41.000000000 +0530 @@ -12,8 +12,14 @@ obj-$(CONFIG_SENSORS_PCF8574) += pcf8574 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 + + diff -Nauprw linux-2.6.20/drivers/i2c/Kconfig ../new/linux-2.6.20/drivers/i2c/Kconfig --- linux-2.6.20/drivers/i2c/Kconfig 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/drivers/i2c/Kconfig 2007-11-21 11:51:41.000000000 +0530 @@ -34,6 +34,7 @@ config I2C_CHARDEV 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 diff -Nauprw linux-2.6.20/drivers/i2c/Makefile ../new/linux-2.6.20/drivers/i2c/Makefile --- linux-2.6.20/drivers/i2c/Makefile 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/drivers/i2c/Makefile 2007-11-21 11:51:41.000000000 +0530 @@ -1,9 +1,10 @@ # -# 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) diff -Nauprw linux-2.6.20/drivers/input/input.c ../new/linux-2.6.20/drivers/input/input.c --- linux-2.6.20/drivers/input/input.c 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/drivers/input/input.c 2007-11-21 11:51:41.000000000 +0530 @@ -928,6 +928,19 @@ struct input_dev *input_allocate_device( } 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 diff -Nauprw linux-2.6.20/drivers/input/keyboard/Kconfig ../new/linux-2.6.20/drivers/input/keyboard/Kconfig --- linux-2.6.20/drivers/input/keyboard/Kconfig 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/drivers/input/keyboard/Kconfig 2007-11-21 11:51:41.000000000 +0530 @@ -214,4 +214,17 @@ config KEYBOARD_AAED2000 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 diff -Nauprw linux-2.6.20/drivers/input/keyboard/kpd-nomadik.c ../new/linux-2.6.20/drivers/input/keyboard/kpd-nomadik.c --- linux-2.6.20/drivers/input/keyboard/kpd-nomadik.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/input/keyboard/kpd-nomadik.c 2008-07-04 23:45:18.000000000 +0530 @@ -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"); diff -Nauprw linux-2.6.20/drivers/input/keyboard/Makefile ../new/linux-2.6.20/drivers/input/keyboard/Makefile --- linux-2.6.20/drivers/input/keyboard/Makefile 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/drivers/input/keyboard/Makefile 2007-11-21 11:51:41.000000000 +0530 @@ -4,6 +4,10 @@ # 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 @@ -18,4 +22,7 @@ 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 diff -Nauprw linux-2.6.20/drivers/input/touchscreen/Kconfig ../new/linux-2.6.20/drivers/input/touchscreen/Kconfig --- linux-2.6.20/drivers/input/touchscreen/Kconfig 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/drivers/input/touchscreen/Kconfig 2007-11-21 11:51:41.000000000 +0530 @@ -159,4 +159,24 @@ config TOUCHSCREEN_UCB1400 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 diff -Nauprw linux-2.6.20/drivers/input/touchscreen/Makefile ../new/linux-2.6.20/drivers/input/touchscreen/Makefile --- linux-2.6.20/drivers/input/touchscreen/Makefile 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/drivers/input/touchscreen/Makefile 2007-11-21 11:51:41.000000000 +0530 @@ -2,6 +2,10 @@ # 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 @@ -16,3 +20,7 @@ obj-$(CONFIG_TOUCHSCREEN_PENMOUNT) += pe 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 diff -Nauprw linux-2.6.20/drivers/input/touchscreen/touchp2003-nomadik.c ../new/linux-2.6.20/drivers/input/touchscreen/touchp2003-nomadik.c --- linux-2.6.20/drivers/input/touchscreen/touchp2003-nomadik.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/input/touchscreen/touchp2003-nomadik.c 2008-07-04 23:45:18.000000000 +0530 @@ -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); diff -Nauprw linux-2.6.20/drivers/input/touchscreen/touchp-nomadik.c ../new/linux-2.6.20/drivers/input/touchscreen/touchp-nomadik.c --- linux-2.6.20/drivers/input/touchscreen/touchp-nomadik.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/input/touchscreen/touchp-nomadik.c 2008-07-04 23:45:19.000000000 +0530 @@ -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"); diff -Nauprw linux-2.6.20/drivers/Makefile ../new/linux-2.6.20/drivers/Makefile --- linux-2.6.20/drivers/Makefile 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/drivers/Makefile 2007-11-21 11:51:41.000000000 +0530 @@ -5,6 +5,7 @@ # Rewritten to use lists instead of if-statements. # +obj-$(CONFIG_I2C) += i2c/ obj-$(CONFIG_PCI) += pci/ obj-$(CONFIG_PARISC) += parisc/ obj-$(CONFIG_RAPIDIO) += rapidio/ @@ -57,7 +58,6 @@ obj-$(CONFIG_GAMEPORT) += input/gamepor 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/ diff -Nauprw linux-2.6.20/drivers/media/Kconfig ../new/linux-2.6.20/drivers/media/Kconfig --- linux-2.6.20/drivers/media/Kconfig 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/Kconfig 2008-08-12 22:56:04.000000000 +0530 @@ -65,6 +65,8 @@ source "drivers/media/dvb/Kconfig" source "drivers/media/common/Kconfig" +source "drivers/media/nomadik_mm/Kconfig" + config VIDEO_TUNER tristate depends on I2C diff -Nauprw linux-2.6.20/drivers/media/Makefile ../new/linux-2.6.20/drivers/media/Makefile --- linux-2.6.20/drivers/media/Makefile 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/Makefile 2008-10-06 12:06:20.000000000 +0530 @@ -6,3 +6,7 @@ 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/ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/hloader/hloader.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/hloader/hloader.c --- linux-2.6.20/drivers/media/nomadik_mm/hcl/hloader/hloader.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/hloader/hloader.c 2008-07-17 16:43:06.000000000 +0530 @@ -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 */ + diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/hloader/hloader.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/hloader/hloader.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/hloader/hloader.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/hloader/hloader.h 2008-07-17 16:43:07.000000000 +0530 @@ -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 */ + diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/hloader/hloader_p.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/hloader/hloader_p.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/hloader/hloader_p.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/hloader/hloader_p.h 2008-07-17 16:43:08.000000000 +0530 @@ -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 */ + diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/include/debug.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/include/debug.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/include/debug.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/include/debug.h 2008-07-17 16:43:02.000000000 +0530 @@ -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 */ + + diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/include/hcl_defs.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/include/hcl_defs.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/include/hcl_defs.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/include/hcl_defs.h 2008-07-17 16:43:03.000000000 +0530 @@ -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 */ + diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/include/hloader.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/include/hloader.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/include/hloader.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/include/hloader.h 2008-07-17 16:43:04.000000000 +0530 @@ -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 */ + diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/include/mupoc_mapping.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/include/mupoc_mapping.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/include/mupoc_mapping.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/include/mupoc_mapping.h 2008-07-17 16:43:04.000000000 +0530 @@ -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 */ + + diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/include/platform_os.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/include/platform_os.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/include/platform_os.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/include/platform_os.h 2008-07-17 16:43:05.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/include/sva.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/include/sva.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/include/sva.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/include/sva.h 2008-07-17 16:43:44.000000000 +0530 @@ -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); +} diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/audio_services.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/audio_services.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/audio_services.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/audio_services.h 2008-07-17 16:42:53.000000000 +0530 @@ -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 */ + diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/ha_api_params.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/ha_api_params.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/ha_api_params.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/ha_api_params.h 2008-07-17 16:42:53.000000000 +0530 @@ -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_ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/ha_codec_info.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/ha_codec_info.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/ha_codec_info.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/ha_codec_info.h 2008-07-17 16:42:54.000000000 +0530 @@ -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_ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/ha_codec_params.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/ha_codec_params.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/ha_codec_params.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/ha_codec_params.h 2008-07-17 16:42:54.000000000 +0530 @@ -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_ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/ha_effect_info.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/ha_effect_info.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/ha_effect_info.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/ha_effect_info.h 2008-07-17 16:42:55.000000000 +0530 @@ -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_ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/ha_effect_params.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/ha_effect_params.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/ha_effect_params.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/ha_effect_params.h 2008-07-17 16:42:55.000000000 +0530 @@ -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_ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/ha_hcl_fw_interface.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/ha_hcl_fw_interface.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/ha_hcl_fw_interface.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/ha_hcl_fw_interface.h 2008-07-17 16:42:56.000000000 +0530 @@ -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_ */ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/hti.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/hti.c --- linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/hti.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/hti.c 2008-07-17 16:42:57.000000000 +0530 @@ -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 + diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/hti.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/hti.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/hti.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/hti.h 2008-07-17 16:42:57.000000000 +0530 @@ -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 + diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/hti_protocol.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/hti_protocol.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/hti_protocol.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/hti_protocol.h 2008-07-17 16:42:58.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/saa_base.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/saa_base.c --- linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/saa_base.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/saa_base.c 2008-07-17 16:43:00.000000000 +0530 @@ -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); + + +} + diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/saa.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/saa.c --- linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/saa.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/saa.c 2008-07-17 16:42:58.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/saa_hwp.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/saa_hwp.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/saa_hwp.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/saa_hwp.h 2008-07-17 16:43:00.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/saa_irq.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/saa_irq.c --- linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/saa_irq.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/saa_irq.c 2008-07-17 16:43:01.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_capabilities.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_capabilities.c --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_capabilities.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_capabilities.c 2008-07-17 16:45:14.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_capabilities.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_capabilities.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_capabilities.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_capabilities.h 2008-07-17 16:45:14.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_fifo.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_fifo.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_fifo.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_fifo.h 2008-07-17 16:45:15.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_hwp.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_hwp.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_hwp.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_hwp.h 2008-07-17 16:45:16.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_internalneeds.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_internalneeds.c --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_internalneeds.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_internalneeds.c 2008-07-17 16:45:16.000000000 +0530 @@ -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; +} diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_internalneeds.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_internalneeds.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_internalneeds.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_internalneeds.h 2008-07-17 16:45:17.000000000 +0530 @@ -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 */ + diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/svap.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/svap.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/svap.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/svap.h 2008-07-17 16:45:19.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_service.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_service.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_service.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_service.h 2008-07-17 16:45:17.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_timemgt.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_timemgt.c --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_timemgt.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_timemgt.c 2008-07-17 16:45:18.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_timemgtp.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_timemgtp.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_timemgtp.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_timemgtp.h 2008-07-17 16:45:19.000000000 +0530 @@ -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 */ + diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264.c --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264.c 2008-08-12 22:56:10.000000000 +0530 @@ -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. */ +/*---------------------------------------------------------------------------*/ +/*------------------------------------------------------------------------ + * 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; +} + diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264_dpb.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264_dpb.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264_dpb.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264_dpb.h 2008-08-12 22:56:12.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264_dpbp.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264_dpbp.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264_dpbp.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264_dpbp.h 2008-07-17 16:45:03.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264.h 2008-07-17 16:45:00.000000000 +0530 @@ -0,0 +1,110 @@ +/*---------------------------------------------------------------------------*/ +/* © 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_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 diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264p.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264p.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264p.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264p.h 2008-07-17 16:45:04.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264_slicemap.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264_slicemap.c --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264_slicemap.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264_slicemap.c 2008-07-17 16:45:03.000000000 +0530 @@ -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]; + +} diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264_slicemap.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264_slicemap.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264_slicemap.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264_slicemap.h 2008-07-17 16:45:04.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg2/sva_dc_mpeg2.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg2/sva_dc_mpeg2.c --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg2/sva_dc_mpeg2.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg2/sva_dc_mpeg2.c 2008-07-17 16:45:05.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg2/sva_dc_mpeg2.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg2/sva_dc_mpeg2.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg2/sva_dc_mpeg2.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg2/sva_dc_mpeg2.h 2008-07-17 16:45:06.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg2/sva_dc_mpeg2p.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg2/sva_dc_mpeg2p.c --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg2/sva_dc_mpeg2p.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg2/sva_dc_mpeg2p.c 2008-07-17 16:45:07.000000000 +0530 @@ -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; +} + diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg2/sva_dc_mpeg2p.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg2/sva_dc_mpeg2p.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg2/sva_dc_mpeg2p.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg2/sva_dc_mpeg2p.h 2008-07-17 16:45:08.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg4/sva_dc_mpeg4.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg4/sva_dc_mpeg4.c --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg4/sva_dc_mpeg4.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg4/sva_dc_mpeg4.c 2008-11-24 14:06:25.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg4/sva_dc_mpeg4.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg4/sva_dc_mpeg4.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg4/sva_dc_mpeg4.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg4/sva_dc_mpeg4.h 2008-07-17 16:45:09.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg4/sva_dc_mpeg4p.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg4/sva_dc_mpeg4p.c --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg4/sva_dc_mpeg4p.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg4/sva_dc_mpeg4p.c 2008-07-17 16:45:10.000000000 +0530 @@ -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; +} + + + diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg4/sva_dc_mpeg4p.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg4/sva_dc_mpeg4p.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg4/sva_dc_mpeg4p.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg4/sva_dc_mpeg4p.h 2008-07-17 16:45:10.000000000 +0530 @@ -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 + diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva_dc_algo.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva_dc_algo.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva_dc_algo.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva_dc_algo.h 2008-07-17 16:44:55.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva_decode.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva_decode.c --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva_decode.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva_decode.c 2008-07-17 16:44:55.000000000 +0530 @@ -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 + + + diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva_decode.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva_decode.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva_decode.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva_decode.h 2008-07-17 16:44:56.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva_decodep.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva_decodep.c --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva_decodep.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva_decodep.c 2008-07-17 16:44:57.000000000 +0530 @@ -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; + +} diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva_decodep.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva_decodep.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva_decodep.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva_decodep.h 2008-07-17 16:44:57.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva_decodepp.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva_decodepp.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva_decodepp.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva_decodepp.h 2008-07-17 16:44:58.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva.h 2008-07-17 16:44:54.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/vc1/sva_dc_vc1.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/vc1/sva_dc_vc1.c --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/vc1/sva_dc_vc1.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/vc1/sva_dc_vc1.c 2008-07-17 16:45:11.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/vc1/sva_dc_vc1.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/vc1/sva_dc_vc1.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/vc1/sva_dc_vc1.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/vc1/sva_dc_vc1.h 2008-07-17 16:45:12.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/vc1/sva_dc_vc1p.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/vc1/sva_dc_vc1p.c --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/vc1/sva_dc_vc1p.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/vc1/sva_dc_vc1p.c 2008-07-17 16:45:13.000000000 +0530 @@ -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; +} + diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/vc1/sva_dc_vc1p.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/vc1/sva_dc_vc1p.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/vc1/sva_dc_vc1p.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/vc1/sva_dc_vc1p.h 2008-07-17 16:45:13.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/display/sva_display.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/display/sva_display.c --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/display/sva_display.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/display/sva_display.c 2008-07-17 16:44:51.000000000 +0530 @@ -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); + +} diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/display/sva_display.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/display/sva_display.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/display/sva_display.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/display/sva_display.h 2008-07-17 16:44:53.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/display/sva_displayp.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/display/sva_displayp.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/display/sva_displayp.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/display/sva_displayp.h 2008-07-17 16:44:54.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/brc/sva_brc.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/brc/sva_brc.c --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/brc/sva_brc.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/brc/sva_brc.c 2008-07-17 16:44:43.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/brc/sva_brc.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/brc/sva_brc.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/brc/sva_brc.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/brc/sva_brc.h 2008-07-17 16:44:44.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/brc/sva_brcp.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/brc/sva_brcp.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/brc/sva_brcp.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/brc/sva_brcp.h 2008-07-17 16:44:45.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/h264/sva_ec_h264.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/h264/sva_ec_h264.c --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/h264/sva_ec_h264.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/h264/sva_ec_h264.c 2008-07-17 16:44:46.000000000 +0530 @@ -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 */ + diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/h264/sva_ec_h264.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/h264/sva_ec_h264.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/h264/sva_ec_h264.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/h264/sva_ec_h264.h 2008-07-17 16:44:47.000000000 +0530 @@ -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 */ + diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/h264/sva_ec_h264p.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/h264/sva_ec_h264p.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/h264/sva_ec_h264p.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/h264/sva_ec_h264p.h 2008-07-17 16:44:48.000000000 +0530 @@ -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 */ + diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/mpeg4/sva_ec_mpeg4.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/mpeg4/sva_ec_mpeg4.c --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/mpeg4/sva_ec_mpeg4.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/mpeg4/sva_ec_mpeg4.c 2008-07-17 16:44:49.000000000 +0530 @@ -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 */ + diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/mpeg4/sva_ec_mpeg4.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/mpeg4/sva_ec_mpeg4.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/mpeg4/sva_ec_mpeg4.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/mpeg4/sva_ec_mpeg4.h 2008-07-17 16:44:50.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/mpeg4/sva_ec_mpeg4p.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/mpeg4/sva_ec_mpeg4p.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/mpeg4/sva_ec_mpeg4p.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/mpeg4/sva_ec_mpeg4p.h 2008-07-17 16:44:50.000000000 +0530 @@ -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 */ + diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/sva_ec_algo.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/sva_ec_algo.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/sva_ec_algo.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/sva_ec_algo.h 2008-07-17 16:44:39.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/sva_encode.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/sva_encode.c --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/sva_encode.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/sva_encode.c 2008-07-17 16:44:40.000000000 +0530 @@ -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; +} diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/sva_encode.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/sva_encode.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/sva_encode.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/sva_encode.h 2008-07-17 16:44:42.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/sva_encodep.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/sva_encodep.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/sva_encodep.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/sva_encodep.h 2008-07-17 16:44:42.000000000 +0530 @@ -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 */ + diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/events_management/sva_eventmgt.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/events_management/sva_eventmgt.c --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/events_management/sva_eventmgt.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/events_management/sva_eventmgt.c 2008-07-17 16:44:36.000000000 +0530 @@ -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; +} diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/events_management/sva_eventmgt.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/events_management/sva_eventmgt.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/events_management/sva_eventmgt.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/events_management/sva_eventmgt.h 2008-07-17 16:44:37.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/events_management/sva_eventmgtp.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/events_management/sva_eventmgtp.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/events_management/sva_eventmgtp.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/events_management/sva_eventmgtp.h 2008-07-17 16:44:38.000000000 +0530 @@ -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 */ + diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/events_management/sva_irqmgt.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/events_management/sva_irqmgt.c --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/events_management/sva_irqmgt.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/events_management/sva_irqmgt.c 2008-07-17 16:44:38.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/events_management/sva_irqmgt.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/events_management/sva_irqmgt.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/events_management/sva_irqmgt.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/events_management/sva_irqmgt.h 2008-07-17 16:44:39.000000000 +0530 @@ -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 */ + diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/firmware_management/sva_fwmgt.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/firmware_management/sva_fwmgt.c --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/firmware_management/sva_fwmgt.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/firmware_management/sva_fwmgt.c 2008-07-17 16:44:34.000000000 +0530 @@ -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 */ + diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/firmware_management/sva_fwmgt.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/firmware_management/sva_fwmgt.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/firmware_management/sva_fwmgt.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/firmware_management/sva_fwmgt.h 2008-07-17 16:44:35.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/firmware_management/sva_fwmgtp.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/firmware_management/sva_fwmgtp.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/firmware_management/sva_fwmgtp.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/firmware_management/sva_fwmgtp.h 2008-07-17 16:44:36.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/grab/sva_grab.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/grab/sva_grab.c --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/grab/sva_grab.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/grab/sva_grab.c 2008-07-17 16:44:31.000000000 +0530 @@ -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); + +} + + diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/grab/sva_grab.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/grab/sva_grab.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/grab/sva_grab.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/grab/sva_grab.h 2008-07-17 16:44:33.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/grab/sva_grabp.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/grab/sva_grabp.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/grab/sva_grabp.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/grab/sva_grabp.h 2008-07-17 16:44:34.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_bufferlistmgt.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_bufferlistmgt.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_bufferlistmgt.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_bufferlistmgt.h 2008-07-17 16:44:18.000000000 +0530 @@ -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 + diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_buffermgt.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_buffermgt.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_buffermgt.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_buffermgt.h 2008-07-17 16:44:18.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_capabilities.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_capabilities.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_capabilities.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_capabilities.h 2008-07-17 16:44:19.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_dc_mpeg2.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_dc_mpeg2.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_dc_mpeg2.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_dc_mpeg2.h 2008-07-17 16:44:19.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_decode.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_decode.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_decode.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_decode.h 2008-07-17 16:44:20.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_display.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_display.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_display.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_display.h 2008-07-17 16:44:20.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_encode.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_encode.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_encode.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_encode.h 2008-07-17 16:44:20.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_eventmgt.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_eventmgt.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_eventmgt.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_eventmgt.h 2008-07-17 16:44:21.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_fifo.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_fifo.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_fifo.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_fifo.h 2008-07-17 16:44:21.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_fwmgt.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_fwmgt.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_fwmgt.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_fwmgt.h 2008-07-17 16:44:22.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_grab.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_grab.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_grab.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_grab.h 2008-07-17 16:44:22.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_host_interface.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_host_interface.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_host_interface.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_host_interface.h 2008-07-17 16:44:23.000000000 +0530 @@ -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_ */ + + diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_internalneeds.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_internalneeds.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_internalneeds.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_internalneeds.h 2008-07-17 16:44:23.000000000 +0530 @@ -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 */ + diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_irqmgt.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_irqmgt.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_irqmgt.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_irqmgt.h 2008-07-17 16:44:24.000000000 +0530 @@ -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 */ + diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_memorymgt.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_memorymgt.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_memorymgt.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_memorymgt.h 2008-07-17 16:44:24.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_openservice.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_openservice.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_openservice.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_openservice.h 2008-07-17 16:44:25.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/svap.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/svap.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/svap.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/svap.h 2008-07-17 16:44:29.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_service.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_service.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_service.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_service.h 2008-07-17 16:44:26.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_stab.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_stab.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_stab.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_stab.h 2008-07-17 16:44:26.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_still_decode.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_still_decode.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_still_decode.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_still_decode.h 2008-07-17 16:44:27.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_still_encode.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_still_encode.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_still_encode.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_still_encode.h 2008-07-17 16:44:27.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_taskmgt.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_taskmgt.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_taskmgt.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_taskmgt.h 2008-07-17 16:44:27.000000000 +0530 @@ -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 */ + diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_timemgt.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_timemgt.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_timemgt.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_timemgt.h 2008-07-17 16:44:28.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_tvo.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_tvo.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_tvo.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_tvo.h 2008-07-17 16:44:28.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/t1xhv_host_interface.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/t1xhv_host_interface.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/t1xhv_host_interface.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/t1xhv_host_interface.h 2008-07-17 16:44:29.000000000 +0530 @@ -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_ */ + + diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/t1xhv_retarget.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/t1xhv_retarget.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/t1xhv_retarget.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/t1xhv_retarget.h 2008-07-17 16:44:31.000000000 +0530 @@ -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_ */ + + diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_bufferlistmgt.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_bufferlistmgt.c --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_bufferlistmgt.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_bufferlistmgt.c 2008-07-17 16:44:12.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_bufferlistmgt.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_bufferlistmgt.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_bufferlistmgt.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_bufferlistmgt.h 2008-07-17 16:44:13.000000000 +0530 @@ -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 + diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_bufferlistmgtp.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_bufferlistmgtp.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_bufferlistmgtp.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_bufferlistmgtp.h 2008-07-17 16:44:13.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_buffermgt.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_buffermgt.c --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_buffermgt.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_buffermgt.c 2008-07-17 16:44:14.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_buffermgt.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_buffermgt.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_buffermgt.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_buffermgt.h 2008-07-17 16:44:15.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_buffermgtp.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_buffermgtp.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_buffermgtp.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_buffermgtp.h 2008-07-17 16:44:15.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_memorymgt.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_memorymgt.c --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_memorymgt.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_memorymgt.c 2008-07-17 16:44:16.000000000 +0530 @@ -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 */ + + diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_memorymgt.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_memorymgt.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_memorymgt.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_memorymgt.h 2008-07-17 16:44:17.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_memorymgtp.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_memorymgtp.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_memorymgtp.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_memorymgtp.h 2008-07-17 16:44:17.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/openservice_management/sva_openservice.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/openservice_management/sva_openservice.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/openservice_management/sva_openservice.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/openservice_management/sva_openservice.h 2008-07-17 16:44:10.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/openservice_management/sva_openservicemgt.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/openservice_management/sva_openservicemgt.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/openservice_management/sva_openservicemgt.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/openservice_management/sva_openservicemgt.h 2008-07-17 16:44:11.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/openservice_management/sva_openservicemgtp.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/openservice_management/sva_openservicemgtp.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/openservice_management/sva_openservicemgtp.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/openservice_management/sva_openservicemgtp.h 2008-07-17 16:44:11.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/stab/sva_stab.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/stab/sva_stab.c --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/stab/sva_stab.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/stab/sva_stab.c 2008-07-17 16:44:05.000000000 +0530 @@ -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; +} diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/stab/sva_stab.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/stab/sva_stab.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/stab/sva_stab.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/stab/sva_stab.h 2008-07-17 16:44:06.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/stab/sva_stabp.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/stab/sva_stabp.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/stab/sva_stabp.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/stab/sva_stabp.h 2008-07-17 16:44:07.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/jpeg/sva_sdc_jpeg.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/jpeg/sva_sdc_jpeg.c --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/jpeg/sva_sdc_jpeg.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/jpeg/sva_sdc_jpeg.c 2008-07-17 16:44:08.000000000 +0530 @@ -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; +} + + diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/jpeg/sva_sdc_jpeg.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/jpeg/sva_sdc_jpeg.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/jpeg/sva_sdc_jpeg.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/jpeg/sva_sdc_jpeg.h 2008-07-17 16:44:08.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/jpeg/sva_sdc_jpegp.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/jpeg/sva_sdc_jpegp.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/jpeg/sva_sdc_jpegp.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/jpeg/sva_sdc_jpegp.h 2008-07-17 16:44:09.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/sva_sdc_algo.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/sva_sdc_algo.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/sva_sdc_algo.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/sva_sdc_algo.h 2008-07-17 16:44:01.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/sva_still_decode.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/sva_still_decode.c --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/sva_still_decode.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/sva_still_decode.c 2008-07-17 16:44:02.000000000 +0530 @@ -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; +} + + diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/sva_still_decode.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/sva_still_decode.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/sva_still_decode.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/sva_still_decode.h 2008-07-17 16:44:03.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/sva_still_decodep.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/sva_still_decodep.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/sva_still_decodep.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/sva_still_decodep.h 2008-07-17 16:44:04.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/jpeg/sva_sec_jpeg.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/jpeg/sva_sec_jpeg.c --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/jpeg/sva_sec_jpeg.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/jpeg/sva_sec_jpeg.c 2008-07-17 16:43:59.000000000 +0530 @@ -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 */ + diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/jpeg/sva_sec_jpeg.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/jpeg/sva_sec_jpeg.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/jpeg/sva_sec_jpeg.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/jpeg/sva_sec_jpeg.h 2008-07-17 16:44:00.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/jpeg/sva_sec_jpegp.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/jpeg/sva_sec_jpegp.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/jpeg/sva_sec_jpegp.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/jpeg/sva_sec_jpegp.h 2008-07-17 16:44:00.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/sva_sec_algo.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/sva_sec_algo.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/sva_sec_algo.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/sva_sec_algo.h 2008-07-17 16:43:56.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/sva_still_encode.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/sva_still_encode.c --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/sva_still_encode.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/sva_still_encode.c 2008-07-17 16:43:56.000000000 +0530 @@ -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; +} +*/ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/sva_still_encode.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/sva_still_encode.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/sva_still_encode.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/sva_still_encode.h 2008-07-17 16:43:58.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/sva_still_encodep.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/sva_still_encodep.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/sva_still_encodep.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/sva_still_encodep.h 2008-07-17 16:43:58.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/sva.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/sva.c --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/sva.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/sva.c 2008-07-17 16:43:46.000000000 +0530 @@ -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; +} + diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/sva.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/sva.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/sva.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/sva.h 2008-07-17 16:43:47.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_hwtaskmgt.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_hwtaskmgt.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_hwtaskmgt.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_hwtaskmgt.h 2008-07-17 16:43:51.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_hwtaskmgtp.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_hwtaskmgtp.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_hwtaskmgtp.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_hwtaskmgtp.h 2008-07-17 16:43:52.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_taskmgt.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_taskmgt.c --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_taskmgt.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_taskmgt.c 2008-07-17 16:43:52.000000000 +0530 @@ -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 */ + diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_taskmgtp.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_taskmgtp.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_taskmgtp.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_taskmgtp.h 2008-07-17 16:43:55.000000000 +0530 @@ -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<. */ +/*---------------------------------------------------------------------------*/ + diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tvo/sva_tvo.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tvo/sva_tvo.c --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tvo/sva_tvo.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tvo/sva_tvo.c 2008-07-17 16:43:48.000000000 +0530 @@ -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; +} diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tvo/sva_tvo.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tvo/sva_tvo.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tvo/sva_tvo.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tvo/sva_tvo.h 2008-07-17 16:43:49.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tvo/sva_tvop.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tvo/sva_tvop.h --- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tvo/sva_tvop.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tvo/sva_tvop.h 2008-07-17 16:43:50.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/Kconfig ../new/linux-2.6.20/drivers/media/nomadik_mm/Kconfig --- linux-2.6.20/drivers/media/nomadik_mm/Kconfig 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/Kconfig 2008-10-06 12:06:22.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/Makefile ../new/linux-2.6.20/drivers/media/nomadik_mm/Makefile --- linux-2.6.20/drivers/media/nomadik_mm/Makefile 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/Makefile 2008-10-06 12:06:21.000000000 +0530 @@ -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/ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/opengl/Makefile ../new/linux-2.6.20/drivers/media/nomadik_mm/opengl/Makefile --- linux-2.6.20/drivers/media/nomadik_mm/opengl/Makefile 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/opengl/Makefile 2008-10-07 12:20:08.000000000 +0530 @@ -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) diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/opengl/ogl.c ../new/linux-2.6.20/drivers/media/nomadik_mm/opengl/ogl.c --- linux-2.6.20/drivers/media/nomadik_mm/opengl/ogl.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/opengl/ogl.c 2008-11-24 14:06:32.000000000 +0530 @@ -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); diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/opengl/ogl.h ../new/linux-2.6.20/drivers/media/nomadik_mm/opengl/ogl.h --- linux-2.6.20/drivers/media/nomadik_mm/opengl/ogl.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/opengl/ogl.h 2008-10-07 12:20:09.000000000 +0530 @@ -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 !!"); diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/opengl/ogl_ioctl.h ../new/linux-2.6.20/drivers/media/nomadik_mm/opengl/ogl_ioctl.h --- linux-2.6.20/drivers/media/nomadik_mm/opengl/ogl_ioctl.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/opengl/ogl_ioctl.h 2008-10-07 12:20:28.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/saa/Makefile ../new/linux-2.6.20/drivers/media/nomadik_mm/saa/Makefile --- linux-2.6.20/drivers/media/nomadik_mm/saa/Makefile 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/saa/Makefile 2008-08-12 22:56:07.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/saa/nomadik-fwload.c ../new/linux-2.6.20/drivers/media/nomadik_mm/saa/nomadik-fwload.c --- linux-2.6.20/drivers/media/nomadik_mm/saa/nomadik-fwload.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/saa/nomadik-fwload.c 2008-07-17 16:42:49.000000000 +0530 @@ -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); diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/saa/nomadik-fwload.h ../new/linux-2.6.20/drivers/media/nomadik_mm/saa/nomadik-fwload.h --- linux-2.6.20/drivers/media/nomadik_mm/saa/nomadik-fwload.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/saa/nomadik-fwload.h 2008-07-17 16:42:49.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/saa/nomadik-saa.c ../new/linux-2.6.20/drivers/media/nomadik_mm/saa/nomadik-saa.c --- linux-2.6.20/drivers/media/nomadik_mm/saa/nomadik-saa.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/saa/nomadik-saa.c 2008-11-24 14:06:25.000000000 +0530 @@ -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); diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/saa/nomadik-saa.h ../new/linux-2.6.20/drivers/media/nomadik_mm/saa/nomadik-saa.h --- linux-2.6.20/drivers/media/nomadik_mm/saa/nomadik-saa.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/saa/nomadik-saa.h 2008-10-06 12:06:21.000000000 +0530 @@ -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*/ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/saa/README ../new/linux-2.6.20/drivers/media/nomadik_mm/saa/README --- linux-2.6.20/drivers/media/nomadik_mm/saa/README 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/saa/README 2008-07-17 16:43:15.000000000 +0530 @@ -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 + + + + + + + + + + + + + + + + + + + + + + + + + diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/saa/saaioctl.h ../new/linux-2.6.20/drivers/media/nomadik_mm/saa/saaioctl.h --- linux-2.6.20/drivers/media/nomadik_mm/saa/saaioctl.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/saa/saaioctl.h 2008-07-17 16:42:51.000000000 +0530 @@ -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 + + + + diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/Makefile ../new/linux-2.6.20/drivers/media/nomadik_mm/sva/Makefile --- linux-2.6.20/drivers/media/nomadik_mm/sva/Makefile 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/sva/Makefile 2008-10-06 12:06:21.000000000 +0530 @@ -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) +# + diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_camera.h ../new/linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_camera.h --- linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_camera.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_camera.h 2008-07-17 16:43:36.000000000 +0530 @@ -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__*/ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_defs.h ../new/linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_defs.h --- linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_defs.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_defs.h 2008-07-17 16:43:37.000000000 +0530 @@ -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__ */ + + + diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_pepperpot.c ../new/linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_pepperpot.c --- linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_pepperpot.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_pepperpot.c 2008-07-17 16:43:37.000000000 +0530 @@ -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 "); + + diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_pepperpot.h ../new/linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_pepperpot.h --- linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_pepperpot.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_pepperpot.h 2008-07-17 16:43:38.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva.c ../new/linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva.c --- linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva.c 2008-11-24 14:06:25.000000000 +0530 @@ -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); + diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva.h ../new/linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva.h --- linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva.h 2008-07-17 16:43:40.000000000 +0530 @@ -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__ */ + + diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_mpeg4.c ../new/linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_mpeg4.c --- linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_mpeg4.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_mpeg4.c 2008-07-17 16:43:41.000000000 +0530 @@ -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; +} + diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_services.h ../new/linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_services.h --- linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_services.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_services.h 2008-11-24 14:06:26.000000000 +0530 @@ -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__*/ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_utils.c ../new/linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_utils.c --- linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_utils.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_utils.c 2008-07-17 16:43:42.000000000 +0530 @@ -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"); +} + + diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_utils.h ../new/linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_utils.h --- linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_utils.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_utils.h 2008-07-17 16:43:43.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new/linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c --- linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c 2008-11-24 14:06:26.000000000 +0530 @@ -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; +} diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.h ../new/linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.h --- linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.h 2008-11-24 14:06:27.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/drivers/media/video/hcl_defs.h ../new/linux-2.6.20/drivers/media/video/hcl_defs.h --- linux-2.6.20/drivers/media/video/hcl_defs.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/video/hcl_defs.h 2007-11-21 11:51:42.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/media/video/Kconfig ../new/linux-2.6.20/drivers/media/video/Kconfig --- linux-2.6.20/drivers/media/video/Kconfig 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/video/Kconfig 2007-11-21 11:51:41.000000000 +0530 @@ -763,4 +763,11 @@ 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 diff -Nauprw linux-2.6.20/drivers/media/video/Makefile ../new/linux-2.6.20/drivers/media/video/Makefile --- linux-2.6.20/drivers/media/video/Makefile 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/video/Makefile 2007-11-21 11:51:41.000000000 +0530 @@ -9,6 +9,8 @@ tuner-objs := tuner-core.o tuner-types.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) @@ -84,6 +86,10 @@ obj-$(CONFIG_VIDEO_BUF_DVB) += video-buf 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/ @@ -112,5 +118,5 @@ obj-$(CONFIG_USB_QUICKCAM_MESSENGER) += 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 diff -Nauprw linux-2.6.20/drivers/media/video/nomadik_camera.h ../new/linux-2.6.20/drivers/media/video/nomadik_camera.h --- linux-2.6.20/drivers/media/video/nomadik_camera.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/video/nomadik_camera.h 2008-07-17 16:42:42.000000000 +0530 @@ -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__*/ diff -Nauprw linux-2.6.20/drivers/media/video/nomadik_defs.h ../new/linux-2.6.20/drivers/media/video/nomadik_defs.h --- linux-2.6.20/drivers/media/video/nomadik_defs.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/video/nomadik_defs.h 2008-07-17 16:42:42.000000000 +0530 @@ -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__ */ + + + diff -Nauprw linux-2.6.20/drivers/media/video/nomadik_sva.h ../new/linux-2.6.20/drivers/media/video/nomadik_sva.h --- linux-2.6.20/drivers/media/video/nomadik_sva.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/video/nomadik_sva.h 2008-07-17 16:42:43.000000000 +0530 @@ -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__ */ + + diff -Nauprw linux-2.6.20/drivers/media/video/nomadik_sva_services.h ../new/linux-2.6.20/drivers/media/video/nomadik_sva_services.h --- linux-2.6.20/drivers/media/video/nomadik_sva_services.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/video/nomadik_sva_services.h 2008-11-24 14:06:24.000000000 +0530 @@ -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__*/ diff -Nauprw linux-2.6.20/drivers/media/video/nomadik_sva_utils.h ../new/linux-2.6.20/drivers/media/video/nomadik_sva_utils.h --- linux-2.6.20/drivers/media/video/nomadik_sva_utils.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/video/nomadik_sva_utils.h 2008-07-17 16:42:44.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/drivers/media/video/platform_os.h ../new/linux-2.6.20/drivers/media/video/platform_os.h --- linux-2.6.20/drivers/media/video/platform_os.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/video/platform_os.h 2007-11-21 11:51:42.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/media/video/sva.h ../new/linux-2.6.20/drivers/media/video/sva.h --- linux-2.6.20/drivers/media/video/sva.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/video/sva.h 2008-07-17 16:42:44.000000000 +0530 @@ -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 "); + + diff -Nauprw linux-2.6.20/drivers/media/video/v4l2-nomadik.h ../new/linux-2.6.20/drivers/media/video/v4l2-nomadik.h --- linux-2.6.20/drivers/media/video/v4l2-nomadik.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/media/video/v4l2-nomadik.h 2008-07-17 16:42:41.000000000 +0530 @@ -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); + + diff -Nauprw linux-2.6.20/drivers/misc/batt-nomadik.c ../new/linux-2.6.20/drivers/misc/batt-nomadik.c --- linux-2.6.20/drivers/misc/batt-nomadik.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/misc/batt-nomadik.c 2008-10-20 13:38:12.000000000 +0530 @@ -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); + diff -Nauprw linux-2.6.20/drivers/misc/etm-nomadik.c ../new/linux-2.6.20/drivers/misc/etm-nomadik.c --- linux-2.6.20/drivers/misc/etm-nomadik.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/misc/etm-nomadik.c 2008-11-19 16:47:03.000000000 +0530 @@ -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"); diff -Nauprw linux-2.6.20/drivers/misc/Kconfig ../new/linux-2.6.20/drivers/misc/Kconfig --- linux-2.6.20/drivers/misc/Kconfig 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/drivers/misc/Kconfig 2008-10-20 13:37:45.000000000 +0530 @@ -2,8 +2,30 @@ # 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 @@ -88,4 +110,9 @@ config MSI_LAPTOP 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 diff -Nauprw linux-2.6.20/drivers/misc/Makefile ../new/linux-2.6.20/drivers/misc/Makefile --- linux-2.6.20/drivers/misc/Makefile 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/drivers/misc/Makefile 2008-10-20 13:37:45.000000000 +0530 @@ -10,3 +10,7 @@ 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 diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/drivers/misc/pexp-nomadik.c --- linux-2.6.20/drivers/misc/pexp-nomadik.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/misc/pexp-nomadik.c 2008-09-17 13:23:32.000000000 +0530 @@ -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"); diff -Nauprw linux-2.6.20/drivers/misc/sif-nomadik.c ../new/linux-2.6.20/drivers/misc/sif-nomadik.c --- linux-2.6.20/drivers/misc/sif-nomadik.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/misc/sif-nomadik.c 2008-10-20 13:37:45.000000000 +0530 @@ -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"); diff -Nauprw linux-2.6.20/drivers/mmc/Kconfig ../new/linux-2.6.20/drivers/mmc/Kconfig --- linux-2.6.20/drivers/mmc/Kconfig 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/drivers/mmc/Kconfig 2007-11-21 11:51:41.000000000 +0530 @@ -125,4 +125,31 @@ config MMC_TIFM_SD 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 diff -Nauprw linux-2.6.20/drivers/mmc/Makefile ../new/linux-2.6.20/drivers/mmc/Makefile --- linux-2.6.20/drivers/mmc/Makefile 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/drivers/mmc/Makefile 2007-11-21 11:51:41.000000000 +0530 @@ -6,21 +6,22 @@ # 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 diff -Nauprw linux-2.6.20/drivers/mmc/mmc-nomadik.c ../new/linux-2.6.20/drivers/mmc/mmc-nomadik.c --- linux-2.6.20/drivers/mmc/mmc-nomadik.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/mmc/mmc-nomadik.c 2007-11-21 11:51:42.000000000 +0530 @@ -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"); diff -Nauprw linux-2.6.20/drivers/mtd/maps/Kconfig ../new/linux-2.6.20/drivers/mtd/maps/Kconfig --- linux-2.6.20/drivers/mtd/maps/Kconfig 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/drivers/mtd/maps/Kconfig 2007-11-21 11:51:41.000000000 +0530 @@ -69,6 +69,13 @@ config MTD_PHYSMAP_OF 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 diff -Nauprw linux-2.6.20/drivers/mtd/maps/Makefile ../new/linux-2.6.20/drivers/mtd/maps/Makefile --- linux-2.6.20/drivers/mtd/maps/Makefile 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/drivers/mtd/maps/Makefile 2007-11-21 11:51:41.000000000 +0530 @@ -7,7 +7,12 @@ 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 @@ -25,7 +30,7 @@ obj-$(CONFIG_MTD_MAINSTONE) += mainstone 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 @@ -33,7 +38,7 @@ 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 @@ -72,3 +77,5 @@ 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 + + diff -Nauprw linux-2.6.20/drivers/mtd/maps/norflash-nomadik.c ../new/linux-2.6.20/drivers/mtd/maps/norflash-nomadik.c --- linux-2.6.20/drivers/mtd/maps/norflash-nomadik.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/mtd/maps/norflash-nomadik.c 2007-11-21 11:51:41.000000000 +0530 @@ -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"); diff -Nauprw linux-2.6.20/drivers/mtd/nand/Kconfig ../new/linux-2.6.20/drivers/mtd/nand/Kconfig --- linux-2.6.20/drivers/mtd/nand/Kconfig 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/drivers/mtd/nand/Kconfig 2007-11-21 11:51:41.000000000 +0530 @@ -13,6 +13,12 @@ config MTD_NAND 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 diff -Nauprw linux-2.6.20/drivers/mtd/nand/Makefile ../new/linux-2.6.20/drivers/mtd/nand/Makefile --- linux-2.6.20/drivers/mtd/nand/Makefile 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/drivers/mtd/nand/Makefile 2007-11-21 11:51:41.000000000 +0530 @@ -24,6 +24,11 @@ obj-$(CONFIG_MTD_NAND_NANDSIM) += nands 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 diff -Nauprw linux-2.6.20/drivers/mtd/nand/nandflash-nomadik.c ../new/linux-2.6.20/drivers/mtd/nand/nandflash-nomadik.c --- linux-2.6.20/drivers/mtd/nand/nandflash-nomadik.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/mtd/nand/nandflash-nomadik.c 2008-07-04 23:45:21.000000000 +0530 @@ -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"); diff -Nauprw linux-2.6.20/drivers/mtd/onenand/generic.c ../new/linux-2.6.20/drivers/mtd/onenand/generic.c --- linux-2.6.20/drivers/mtd/onenand/generic.c 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/drivers/mtd/onenand/generic.c 2008-09-17 13:23:33.000000000 +0530 @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -36,20 +37,30 @@ struct onenand_info { 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; } @@ -96,11 +107,12 @@ out_free_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); @@ -116,27 +128,57 @@ static int __devexit generic_onenand_rem 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); diff -Nauprw linux-2.6.20/drivers/mtd/onenand/Kconfig ../new/linux-2.6.20/drivers/mtd/onenand/Kconfig --- linux-2.6.20/drivers/mtd/onenand/Kconfig 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/drivers/mtd/onenand/Kconfig 2008-11-19 16:47:03.000000000 +0530 @@ -2,20 +2,17 @@ # 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 @@ -25,13 +22,12 @@ config MTD_ONENAND_VERIFY_WRITE 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. @@ -43,4 +39,28 @@ config MTD_ONENAND_OTP 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 + diff -Nauprw linux-2.6.20/drivers/mtd/onenand/Makefile ../new/linux-2.6.20/drivers/mtd/onenand/Makefile --- linux-2.6.20/drivers/mtd/onenand/Makefile 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/drivers/mtd/onenand/Makefile 2008-11-19 16:47:03.000000000 +0530 @@ -8,4 +8,7 @@ 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 diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_base.c ../new/linux-2.6.20/drivers/mtd/onenand/onenand_base.c --- linux-2.6.20/drivers/mtd/onenand/onenand_base.c 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/drivers/mtd/onenand/onenand_base.c 2008-11-19 16:47:03.000000000 +0530 @@ -33,8 +33,8 @@ static struct nand_ecclayout onenand_oob 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}, } }; @@ -61,6 +61,17 @@ static const unsigned char ffchars[] = { 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 @@ -94,16 +105,9 @@ static void onenand_writew(unsigned shor */ 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; } @@ -118,17 +122,11 @@ static int onenand_block_address(struct */ 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 ONENAND_DDP_CHIP1; - return (dbs << ONENAND_DDP_SHIFT); - } - - return 0; + return ONENAND_DDP_CHIP0; } /** @@ -214,6 +212,15 @@ static int onenand_command(struct mtd_in 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; } @@ -224,6 +231,10 @@ static int onenand_command(struct mtd_in 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); @@ -255,6 +266,8 @@ static int onenand_command(struct mtd_in break; default: + if (ONENAND_IS_2PLANE(this) && cmd == ONENAND_CMD_PROG) + cmd = ONENAND_CMD_2X_PROG; dataram = ONENAND_CURRENT_BUFFERRAM(this); break; } @@ -317,23 +330,28 @@ static int onenand_wait(struct mtd_info 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; } @@ -347,7 +365,7 @@ static int onenand_wait(struct mtd_info */ 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) @@ -450,8 +468,9 @@ static inline int onenand_bufferram_offs 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; } @@ -474,14 +493,12 @@ static int onenand_read_bufferram(struct { 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--; @@ -489,9 +506,7 @@ static int onenand_read_bufferram(struct word = this->read_word(bufferram + offset + count); buffer[count] = (word & 0xff); } - - memcpy(buffer, bufferram + offset, count); - + dest=imemcopy(buffer, bufferram + offset, count); return 0; } @@ -510,7 +525,7 @@ static int onenand_sync_read_bufferram(s { struct onenand_chip *this = mtd->priv; void __iomem *bufferram; - + int *dest=NULL; bufferram = this->base + area; bufferram += onenand_bufferram_offset(mtd, area); @@ -528,8 +543,7 @@ static int onenand_sync_read_bufferram(s buffer[count] = (word & 0xff); } - memcpy(buffer, bufferram + offset, count); - + dest=imemcopy(buffer, bufferram + offset, count); this->mmcontrol(mtd, 0); return 0; @@ -550,6 +564,7 @@ static int onenand_write_bufferram(struc { struct onenand_chip *this = mtd->priv; void __iomem *bufferram; + int *dest=NULL; bufferram = this->base + area; @@ -571,12 +586,35 @@ static int onenand_write_bufferram(struc 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 @@ -587,22 +625,35 @@ static int onenand_write_bufferram(struc 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; } /** @@ -613,31 +664,52 @@ static int onenand_check_bufferram(struc * * 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; + } } /** @@ -694,38 +766,85 @@ static void onenand_release_device(struc } /** - * 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 */ @@ -733,47 +852,64 @@ static int onenand_read(struct mtd_info /* 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 */ @@ -781,76 +917,91 @@ static int onenand_read(struct mtd_info 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; @@ -868,27 +1019,185 @@ int onenand_do_read_oob(struct mtd_info } } -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; + + /* 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; - return onenand_do_read_oob(mtd, from + ops->ooboffs, ops->ooblen, - &ops->oobretlen, ops->oobbuf); + /* 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 @@ -897,14 +1206,11 @@ static int onenand_read_oob(struct mtd_i * @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); @@ -913,33 +1219,37 @@ static int onenand_verify_oob(struct mtd 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) @@ -947,101 +1257,175 @@ static int onenand_verify_page(struct mt 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; } @@ -1058,118 +1442,191 @@ 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; +} + +/** + * 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; - *retlen = written; + 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; @@ -1199,19 +1656,19 @@ static int onenand_erase(struct mtd_info /* 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; } @@ -1230,7 +1687,7 @@ static int onenand_erase(struct mtd_info 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; @@ -1238,10 +1695,12 @@ static int onenand_erase(struct mtd_info 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; @@ -1256,13 +1715,14 @@ static int onenand_erase(struct mtd_info 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; } @@ -1292,11 +1752,16 @@ static void onenand_sync(struct mtd_info */ 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; } /** @@ -1312,7 +1777,12 @@ static int onenand_default_block_markbad 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 */ @@ -1322,7 +1792,7 @@ static int onenand_default_block_markbad /* 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); } /** @@ -1345,7 +1815,10 @@ static int onenand_block_markbad(struct 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; } /** @@ -1353,6 +1826,7 @@ static int onenand_block_markbad(struct * @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 */ @@ -1435,7 +1909,12 @@ static int onenand_do_lock_cmd(struct mt */ 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; } /** @@ -1448,7 +1927,12 @@ static int onenand_lock(struct mtd_info */ 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; } /** @@ -1491,6 +1975,8 @@ static int onenand_unlock_all(struct 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); @@ -1503,15 +1989,12 @@ static int onenand_unlock_all(struct mtd 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); @@ -1519,7 +2002,7 @@ static int onenand_unlock_all(struct mtd return 0; } - onenand_unlock(mtd, 0x0, this->chipsize); + onenand_do_lock_cmd(mtd, 0x0, this->chipsize, ONENAND_CMD_UNLOCK); return 0; } @@ -1544,13 +2027,19 @@ static int do_otp_read(struct mtd_info * 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); @@ -1562,19 +2051,20 @@ 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) { @@ -1588,7 +2078,12 @@ static int do_otp_write(struct mtd_info 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); @@ -1611,13 +2106,21 @@ static int do_otp_lock(struct mtd_info * 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); @@ -1664,13 +2167,16 @@ static int onenand_otp_walk(struct mtd_i 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; @@ -1690,13 +2196,14 @@ static int onenand_otp_walk(struct mtd_i len -= size; *retlen += size; - if (ret < 0) - return ret; + if (ret) + break; } otp_pages--; } + onenand_release_device(mtd); - return 0; + return ret; } /** @@ -1823,12 +2330,14 @@ static int onenand_lock_user_prot_reg(st #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; @@ -1838,31 +2347,47 @@ static void onenand_lock_scheme(struct m 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; @@ -1873,7 +2398,7 @@ static void onenand_print_device_info(in (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[] = { @@ -1911,12 +2436,12 @@ static int onenand_check_maf(int manuf) * @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; @@ -1948,6 +2473,7 @@ static int onenand_probe(struct mtd_info 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) @@ -1961,26 +2487,41 @@ static int onenand_probe(struct mtd_info 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; } @@ -2021,6 +2562,7 @@ static void onenand_resume(struct mtd_in */ int onenand_scan(struct mtd_info *mtd, int maxchips) { + int i; struct onenand_chip *this = mtd->priv; if (!this->read_word) @@ -2044,7 +2586,9 @@ int onenand_scan(struct mtd_info *mtd, i 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) { @@ -2054,15 +2598,25 @@ int onenand_scan(struct mtd_info *mtd, i /* 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); @@ -2092,12 +2646,23 @@ int onenand_scan(struct mtd_info *mtd, i } 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; @@ -2144,11 +2709,16 @@ void onenand_release(struct mtd_info *mt 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); @@ -2157,3 +2727,4 @@ EXPORT_SYMBOL_GPL(onenand_release); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Kyungmin Park "); MODULE_DESCRIPTION("Generic OneNAND flash driver code"); + diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_bbt.c ../new/linux-2.6.20/drivers/mtd/onenand/onenand_bbt.c --- linux-2.6.20/drivers/mtd/onenand/onenand_bbt.c 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/drivers/mtd/onenand/onenand_bbt.c 2008-09-17 13:23:33.000000000 +0530 @@ -10,6 +10,11 @@ * * 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 @@ -17,8 +22,8 @@ #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 @@ -65,10 +70,11 @@ static int create_bbt(struct mtd_info *m 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; @@ -82,22 +88,24 @@ static int create_bbt(struct mtd_info *m 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); @@ -167,9 +175,8 @@ static int onenand_isbad_bbt(struct mtd_ * 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) diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_sim.c ../new/linux-2.6.20/drivers/mtd/onenand/onenand_sim.c --- linux-2.6.20/drivers/mtd/onenand/onenand_sim.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/mtd/onenand/onenand_sim.c 2008-11-19 16:47:10.000000000 +0530 @@ -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"); diff -Nauprw linux-2.6.20/drivers/net/kgdboe.c ../new/linux-2.6.20/drivers/net/kgdboe.c --- linux-2.6.20/drivers/net/kgdboe.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/net/kgdboe.c 2007-11-21 11:51:41.000000000 +0530 @@ -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"); diff -Nauprw linux-2.6.20/drivers/net/Makefile ../new/linux-2.6.20/drivers/net/Makefile --- linux-2.6.20/drivers/net/Makefile 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/drivers/net/Makefile 2007-11-21 11:51:41.000000000 +0530 @@ -213,6 +213,7 @@ 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/ diff -Nauprw linux-2.6.20/drivers/net/smc91x.c ../new/linux-2.6.20/drivers/net/smc91x.c --- linux-2.6.20/drivers/net/smc91x.c 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/drivers/net/smc91x.c 2007-11-21 11:51:41.000000000 +0530 @@ -1,3 +1,4 @@ + /* * smc91x.c * This is a driver for SMSC's 91C9x/91C1xx single-chip Ethernet devices. @@ -65,7 +66,6 @@ static const char version[] = #define SMC_DEBUG 0 #endif - #include #include #include @@ -90,6 +90,8 @@ static const char version[] = #include "smc91x.h" +#include + #ifdef CONFIG_ISA /* * the LAN91C111 can be at any of the following port addresses. To change, @@ -268,7 +270,6 @@ static void PRINT_PKT(u_char *buf, int l #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; \ @@ -308,7 +309,6 @@ static void PRINT_PKT(u_char *buf, int l } \ } while (0) - /* * this does a soft reset on the device */ @@ -494,8 +494,7 @@ static inline void smc_rcv(struct net_d 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)) { @@ -835,7 +834,6 @@ static void smc_tx(struct net_device *de SMC_SELECT_BANK(2); } - /*---PHY CONTROL AND CONFIGURATION-----------------------------------------*/ static void smc_mii_out(struct net_device *dev, unsigned int val, int bits) @@ -927,7 +925,9 @@ static void smc_phy_write(struct net_dev 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)); @@ -961,8 +961,7 @@ static void smc_phy_detect(struct net_de 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 && @@ -1184,7 +1183,9 @@ static void smc_phy_configure(struct wor /* 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); @@ -1314,11 +1315,12 @@ static irqreturn_t smc_interrupt(int irq 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) @@ -1354,10 +1356,18 @@ static irqreturn_t smc_interrupt(int irq /* 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++; @@ -1500,7 +1510,8 @@ static void smc_set_multicast_list(struc 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)); @@ -1553,14 +1564,12 @@ static void smc_set_multicast_list(struc 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); @@ -1659,8 +1668,7 @@ smc_ethtool_getsettings(struct net_devic 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; @@ -1670,7 +1678,8 @@ smc_ethtool_getsettings(struct net_devic 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; } @@ -1691,8 +1700,8 @@ smc_ethtool_setsettings(struct net_devic } 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; @@ -1712,7 +1721,8 @@ smc_ethtool_getdrvinfo(struct net_device { 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) @@ -1839,7 +1849,7 @@ static int __init smc_findirq(void __iom * 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; @@ -1880,6 +1890,8 @@ static int __init smc_probe(struct net_d * 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) { @@ -1918,6 +1930,7 @@ static int __init smc_probe(struct net_d /* 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 */ @@ -2005,7 +2018,11 @@ static int __init smc_probe(struct net_d } /* 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; @@ -2045,7 +2062,8 @@ 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); } @@ -2066,7 +2084,8 @@ static int smc_enable_device(struct plat 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; @@ -2122,7 +2141,8 @@ static int smc_enable_device(struct plat 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; @@ -2135,7 +2155,8 @@ static int smc_request_attrib(struct pla 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); @@ -2159,8 +2180,12 @@ static inline void smc_request_datacs(st } } -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"); @@ -2201,7 +2226,6 @@ static int smc_drv_probe(struct platform goto out; } - if (!request_mem_region(res->start, SMC_IO_EXTENT, CARDNAME)) { ret = -EBUSY; goto out; @@ -2240,6 +2264,7 @@ static int smc_drv_probe(struct platform } platform_set_drvdata(pdev, ndev); + ret = smc_probe(ndev, addr); if (ret != 0) goto out_iounmap; @@ -2278,7 +2303,6 @@ static int smc_drv_remove(struct platfor platform_set_drvdata(pdev, NULL); unregister_netdev(ndev); - free_irq(ndev->irq, ndev); #ifdef SMC_USE_PXA_DMA @@ -2348,8 +2372,6 @@ static int __init smc_init(void) #ifdef CONFIG_ISA if (io == -1) printk(KERN_WARNING - "%s: You shouldn't use auto-probing with insmod!\n", - CARDNAME); #endif #endif diff -Nauprw linux-2.6.20/drivers/net/smc91x.h ../new/linux-2.6.20/drivers/net/smc91x.h --- linux-2.6.20/drivers/net/smc91x.h 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/drivers/net/smc91x.h 2007-11-21 11:51:41.000000000 +0530 @@ -34,7 +34,6 @@ #ifndef _SMC91X_H_ #define _SMC91X_H_ - /* * Define your architecture specific bus configuration parameters here. */ @@ -163,8 +162,7 @@ #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; @@ -199,6 +197,77 @@ SMC_outw(u16 val, void __iomem *ioaddr, || (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) @@ -477,7 +546,6 @@ smc_pxa_dma_irq(int dma, void *dummy) } #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 @@ -485,12 +553,14 @@ smc_pxa_dma_irq(int dma, void *dummy) * 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() @@ -522,14 +592,18 @@ smc_pxa_dma_irq(int dma, void *dummy) #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 @@ -569,7 +643,6 @@ smc_pxa_dma_irq(int dma, void *dummy) */ #define BANK_SELECT (14 << SMC_IO_SHIFT) - // Transmit Control Register /* BANK 0 */ #define TCR_REG SMC_REG(0x0000, 0) @@ -588,7 +661,6 @@ smc_pxa_dma_irq(int dma, void *dummy) /* 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) @@ -607,7 +679,6 @@ smc_pxa_dma_irq(int dma, void *dummy) #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) @@ -624,17 +695,14 @@ smc_pxa_dma_irq(int dma, void *dummy) #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) @@ -661,14 +729,12 @@ smc_pxa_dma_irq(int dma, void *dummy) #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) @@ -680,24 +746,20 @@ smc_pxa_dma_irq(int dma, void *dummy) // 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) @@ -710,7 +772,6 @@ smc_pxa_dma_irq(int dma, void *dummy) #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) @@ -724,18 +785,15 @@ smc_pxa_dma_irq(int dma, void *dummy) #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) @@ -755,17 +813,14 @@ smc_pxa_dma_irq(int dma, void *dummy) #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) @@ -778,7 +833,6 @@ smc_pxa_dma_irq(int dma, void *dummy) #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) @@ -786,7 +840,6 @@ smc_pxa_dma_irq(int dma, void *dummy) #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) @@ -796,13 +849,11 @@ smc_pxa_dma_irq(int dma, void *dummy) #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 */ @@ -810,12 +861,10 @@ smc_pxa_dma_irq(int dma, void *dummy) #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 @@ -834,8 +883,8 @@ static const char * chip_ids[ 16 ] = { /* 8 */ "SMC91C100FD", /* 9 */ "SMC91C11xFD", NULL, NULL, NULL, - NULL, NULL, NULL}; - + NULL, NULL, NULL +}; /* . Receive status bits @@ -849,7 +898,6 @@ static const char * chip_ids[ 16 ] = { #define RS_MULTICAST 0x0001 #define RS_ERRORS (RS_ALGNERR | RS_BADCRC | RS_TOOLONG | RS_TOOSHORT) - /* * PHY IDs * LAN83C183 == LAN91C111 Internal PHY @@ -879,7 +927,6 @@ static const char * chip_ids[ 16 ] = { #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 @@ -904,7 +951,6 @@ static const char * chip_ids[ 16 ] = { #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. @@ -922,7 +968,6 @@ static const char * chip_ids[ 16 ] = { #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. @@ -1089,7 +1134,13 @@ static const char * chip_ids[ 16 ] = { #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 ); \ @@ -1099,6 +1150,18 @@ static const char * chip_ids[ 16 ] = { __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; \ + __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) +#endif #endif #define SMC_SET_MAC_ADDR(addr) \ diff -Nauprw linux-2.6.20/drivers/serial/amba-pl011.c ../new/linux-2.6.20/drivers/serial/amba-pl011.c --- linux-2.6.20/drivers/serial/amba-pl011.c 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/drivers/serial/amba-pl011.c 2007-11-21 11:51:41.000000000 +0530 @@ -52,13 +52,32 @@ #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) @@ -102,9 +121,16 @@ 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) @@ -115,6 +141,7 @@ static void pl011_rx_chars(struct uart_a 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++; @@ -174,7 +201,9 @@ static void pl011_tx_chars(struct uart_a } 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++; @@ -318,6 +347,7 @@ static int pl011_startup(struct uart_por struct uart_amba_port *uap = (struct uart_amba_port *)port; unsigned int cr; int retval; + int status, ch; /* * Try to enable the clock producer. @@ -331,12 +361,19 @@ static int pl011_startup(struct uart_por /* * 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. @@ -346,7 +383,11 @@ static int pl011_startup(struct uart_por 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(); @@ -356,7 +397,14 @@ static int pl011_startup(struct uart_por /* * 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 @@ -396,7 +444,8 @@ static void pl011_shutdown(struct uart_p /* * 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 @@ -658,6 +707,7 @@ static int __init pl011_console_setup(st * 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]; @@ -700,6 +750,28 @@ static struct uart_driver amba_reg = { .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; @@ -739,9 +811,10 @@ static int pl011_probe(struct amba_devic 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; @@ -782,8 +855,8 @@ static int pl011_remove(struct amba_devi static struct amba_id pl011_ids[] __initdata = { { - .id = 0x00041011, - .mask = 0x000fffff, + .id = UART_PER_ID, + .mask = UART_PER_MASK, }, { 0, 0 }, }; @@ -795,6 +868,10 @@ static struct amba_driver pl011_driver = .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) diff -Nauprw linux-2.6.20/drivers/spi/Kconfig ../new/linux-2.6.20/drivers/spi/Kconfig --- linux-2.6.20/drivers/spi/Kconfig 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/drivers/spi/Kconfig 2007-11-21 11:51:41.000000000 +0530 @@ -65,6 +65,14 @@ config SPI_BITBANG 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 diff -Nauprw linux-2.6.20/drivers/spi/Makefile ../new/linux-2.6.20/drivers/spi/Makefile --- linux-2.6.20/drivers/spi/Makefile 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/drivers/spi/Makefile 2007-11-21 11:51:41.000000000 +0530 @@ -12,6 +12,8 @@ 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 diff -Nauprw linux-2.6.20/drivers/spi/spi-nomadik.c ../new/linux-2.6.20/drivers/spi/spi-nomadik.c --- linux-2.6.20/drivers/spi/spi-nomadik.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/spi/spi-nomadik.c 2008-07-04 23:45:22.000000000 +0530 @@ -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 + +#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 */ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/debug.h ../new/linux-2.6.20/drivers/usb/nomadik/debug.h --- linux-2.6.20/drivers/usb/nomadik/debug.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/usb/nomadik/debug.h 2008-07-28 15:20:49.000000000 +0530 @@ -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__ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/dma.h ../new/linux-2.6.20/drivers/usb/nomadik/dma.h --- linux-2.6.20/drivers/usb/nomadik/dma.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/usb/nomadik/dma.h 2008-07-28 15:20:50.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/g_ep0.c ../new/linux-2.6.20/drivers/usb/nomadik/g_ep0.c --- linux-2.6.20/drivers/usb/nomadik/g_ep0.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/usb/nomadik/g_ep0.c 2008-08-08 19:15:20.000000000 +0530 @@ -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; +} diff -Nauprw linux-2.6.20/drivers/usb/nomadik/Kconfig ../new/linux-2.6.20/drivers/usb/nomadik/Kconfig --- linux-2.6.20/drivers/usb/nomadik/Kconfig 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/usb/nomadik/Kconfig 2008-07-04 23:45:35.000000000 +0530 @@ -0,0 +1,176 @@ +# +# INVENTRA USB Host Controller Drivers +# +# $Revision: 1.13 $ +# +config USB_INVENTRA_HCD + depends on USB + tristate 'Inventra HCD Controller Support' + help + Say Y here if you have the Inventra USB board on your system. + + If you do not know what this is, please say N. + + To compile this driver as a module, choose M here: the + module will be called musb-hcd (host controller) or + musb-gcd (gadget controller) or musb-icd (interface + controller when OTG is enabled). + +choice +prompt "Controller Mode" +depends on USB_INVENTRA_HCD +default USB_INVENTRA_HCD_HOST + +config USB_INVENTRA_HCD_HOST + bool 'Host Mode' + +config USB_INVENTRA_HCD_GADGET_API + bool 'GADGET API' + help + Say Y here if you want support for GADGET API; the module will + be called musb-gcd.ko + + You will need to select the Inventra Controller in the Gadget + subsection. + + If you do not know what this is, please say N. + +config USB_INVENTRA_HCD_OTG + bool 'On The Go' + help + Say Y here if you want support for USB On The Go. + + The module will be called musb-icd.ko + + If you do not know what this is, please say N. + +#config USB_INVENTRA_HCD_GSTORAGE +# bool 'Storage Demo' +# help +# Say Y here if you want the hcd driver compiled as +# like a mass storage device. +# +# If you do not know what this is, please say N. + +config USB_INVENTRA_HCD_OTG_GSTORAGE + bool 'OTG Storage Demo' + help + Say Y here if you want the hcd driver compiled as + a mass storage device with OTG support. + + If you do not know what this is, please say N. + + +endchoice + +config USB_INVENTRA_STATIC_CONFIG + depends on USB_INVENTRA_HCD + bool 'Use static config (-DMUSB_STATIC_CONFIG)' + default true + help + Use the static configuration file. File must be called + hdrc_cnf.h and mut be generated from the board configuration + file. Please check directory install/configs for examples. + + If usure please say please say N and make sure your controller + is using the standard configuration HB+8E(8K)+8DMA + + NOTE: Make sure your board is using the corresponding core. + +config USB_INVENTRA_MUSB_EPFIFOCONFIG_FILE + depends on USB_INVENTRA_STATIC_CONFIG + string 'Endpoint FIFO configuration file (Advanced)' + default '' + help + Specify the file with the endpoint fifo configuration (Advanced). The + file shoud define an struct MUSB_EpFifoDescriptor array called + MUSB_aEpFifoDescriptors[MUSB_C_NUM_EPS] containig the end point FIFO + configuration specs. Check musbdefs.h for more informations; + + 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 } + + }; + + gives the endpoint 0 its default value, and defines ep1/ep2 as bulk tx/rx + 512 bytes in size each with double buffering disabled. The FIFO memory + allocated with this confoguration is 64+512+512=1088 bytes + +config USB_INVENTRA_DMA + depends on USB_INVENTRA_HCD + bool 'Use DMA when possible (-DMUSB_DMA)' + default true + help + Enable DMA transfers when DMA is possible + +config USB_INVENTRA_MUSB_HAS_AHB_ID + depends on USB_INVENTRA_HCD + bool 'Enable AHB_ID (-DMUSB_AHB_ID)' + default false + help + Disable auto core identification. + + NOTE: Make sure your board is using the corresponding core. + +config USB_INVENTRA_MUSB_HDR_CCNF_FILE + depends on USB_INVENTRA_HCD + string 'Custom config file (Advanced)' + default '' + help + Specify a custom config file (Advanced) + +config USB_INVENTRA_MUSB_BOARD_FILE + depends on USB_INVENTRA_HCD + string 'Custom board file (Advanced)' + default '' + help + Specify a custom board file (Advanced) + +config USB_INVENTRA_TPL + depends on USB_INVENTRA_HCD_OTG + tristate ' Use TPL (-DMUSB_TPL)' + default false + help + Enable Target Peripheral List + +config USB_INVENTRA_PROC_TESTMUSB + depends on USB_INVENTRA_HCD && PROC_FS && ( USB_INVENTRA_HOSTMODE || USB_INVENTRA_OTG ) + bool 'Enable /proc/testmusbhdrc*' + default false + help + Add /proc/testmusbhdrc 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. + diff -Nauprw linux-2.6.20/drivers/usb/nomadik/logx ../new/linux-2.6.20/drivers/usb/nomadik/logx --- linux-2.6.20/drivers/usb/nomadik/logx 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/usb/nomadik/logx 2008-07-04 23:45:36.000000000 +0530 @@ -0,0 +1 @@ +make: *** No rule to make target `vmlinux'. Stop. diff -Nauprw linux-2.6.20/drivers/usb/nomadik/Makefile ../new/linux-2.6.20/drivers/usb/nomadik/Makefile --- linux-2.6.20/drivers/usb/nomadik/Makefile 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/usb/nomadik/Makefile 2008-07-04 23:45:36.000000000 +0530 @@ -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) + diff -Nauprw linux-2.6.20/drivers/usb/nomadik/musb_bus_direct.c ../new/linux-2.6.20/drivers/usb/nomadik/musb_bus_direct.c --- linux-2.6.20/drivers/usb/nomadik/musb_bus_direct.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/usb/nomadik/musb_bus_direct.c 2008-08-08 19:15:21.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/drivers/usb/nomadik/musb_cross.h ../new/linux-2.6.20/drivers/usb/nomadik/musb_cross.h --- linux-2.6.20/drivers/usb/nomadik/musb_cross.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/usb/nomadik/musb_cross.h 2008-08-08 19:15:22.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/drivers/usb/nomadik/musb_debug.c ../new/linux-2.6.20/drivers/usb/nomadik/musb_debug.c --- linux-2.6.20/drivers/usb/nomadik/musb_debug.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/usb/nomadik/musb_debug.c 2008-07-28 15:20:53.000000000 +0530 @@ -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; +} + + diff -Nauprw linux-2.6.20/drivers/usb/nomadik/musbdefs.h ../new/linux-2.6.20/drivers/usb/nomadik/musbdefs.h --- linux-2.6.20/drivers/usb/nomadik/musbdefs.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/usb/nomadik/musbdefs.h 2008-08-08 19:15:30.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/musb_epdescriptors.h ../new/linux-2.6.20/drivers/usb/nomadik/musb_epdescriptors.h --- linux-2.6.20/drivers/usb/nomadik/musb_epdescriptors.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/usb/nomadik/musb_epdescriptors.h 2008-09-17 13:23:33.000000000 +0530 @@ -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 +*/ + diff -Nauprw linux-2.6.20/drivers/usb/nomadik/musb_epfifocfg.c ../new/linux-2.6.20/drivers/usb/nomadik/musb_epfifocfg.c --- linux-2.6.20/drivers/usb/nomadik/musb_epfifocfg.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/usb/nomadik/musb_epfifocfg.c 2008-07-28 15:20:55.000000000 +0530 @@ -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 + diff -Nauprw linux-2.6.20/drivers/usb/nomadik/musb_hcd.c ../new/linux-2.6.20/drivers/usb/nomadik/musb_hcd.c --- linux-2.6.20/drivers/usb/nomadik/musb_hcd.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/usb/nomadik/musb_hcd.c 2008-09-17 13:23:33.000000000 +0530 @@ -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; +} diff -Nauprw linux-2.6.20/drivers/usb/nomadik/musbhdrc.h ../new/linux-2.6.20/drivers/usb/nomadik/musbhdrc.h --- linux-2.6.20/drivers/usb/nomadik/musbhdrc.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/usb/nomadik/musbhdrc.h 2008-08-08 19:15:31.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/musb_host.c ../new/linux-2.6.20/drivers/usb/nomadik/musb_host.c --- linux-2.6.20/drivers/usb/nomadik/musb_host.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/usb/nomadik/musb_host.c 2008-08-08 19:15:25.000000000 +0530 @@ -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 + diff -Nauprw linux-2.6.20/drivers/usb/nomadik/musb_host.h ../new/linux-2.6.20/drivers/usb/nomadik/musb_host.h --- linux-2.6.20/drivers/usb/nomadik/musb_host.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/usb/nomadik/musb_host.h 2008-07-28 15:20:59.000000000 +0530 @@ -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 */ + diff -Nauprw linux-2.6.20/drivers/usb/nomadik/musbhsfc.h ../new/linux-2.6.20/drivers/usb/nomadik/musbhsfc.h --- linux-2.6.20/drivers/usb/nomadik/musbhsfc.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/usb/nomadik/musbhsfc.h 2008-08-08 19:15:31.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/musb_ioctl.c ../new/linux-2.6.20/drivers/usb/nomadik/musb_ioctl.c --- linux-2.6.20/drivers/usb/nomadik/musb_ioctl.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/usb/nomadik/musb_ioctl.c 2008-08-08 19:15:27.000000000 +0530 @@ -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 + diff -Nauprw linux-2.6.20/drivers/usb/nomadik/musb_ioctl.h ../new/linux-2.6.20/drivers/usb/nomadik/musb_ioctl.h --- linux-2.6.20/drivers/usb/nomadik/musb_ioctl.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/usb/nomadik/musb_ioctl.h 2008-07-28 15:21:00.000000000 +0530 @@ -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 + diff -Nauprw linux-2.6.20/drivers/usb/nomadik/musb_plat_uds.c ../new/linux-2.6.20/drivers/usb/nomadik/musb_plat_uds.c --- linux-2.6.20/drivers/usb/nomadik/musb_plat_uds.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/usb/nomadik/musb_plat_uds.c 2008-09-17 13:23:34.000000000 +0530 @@ -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 + diff -Nauprw linux-2.6.20/drivers/usb/nomadik/musb_procfs.c ../new/linux-2.6.20/drivers/usb/nomadik/musb_procfs.c --- linux-2.6.20/drivers/usb/nomadik/musb_procfs.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/usb/nomadik/musb_procfs.c 2008-08-08 19:15:29.000000000 +0530 @@ -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; +} + diff -Nauprw linux-2.6.20/drivers/usb/nomadik/musb_virthub.c ../new/linux-2.6.20/drivers/usb/nomadik/musb_virthub.c --- linux-2.6.20/drivers/usb/nomadik/musb_virthub.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/usb/nomadik/musb_virthub.c 2008-07-28 15:21:03.000000000 +0530 @@ -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"); +} diff -Nauprw linux-2.6.20/drivers/usb/nomadik/musb_virthub.h ../new/linux-2.6.20/drivers/usb/nomadik/musb_virthub.h --- linux-2.6.20/drivers/usb/nomadik/musb_virthub.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/usb/nomadik/musb_virthub.h 2008-07-28 15:21:05.000000000 +0530 @@ -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 */ + diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c --- linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c 2008-09-17 13:23:34.000000000 +0530 @@ -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); diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.h ../new/linux-2.6.20/drivers/usb/nomadik/nomadik_udc.h --- linux-2.6.20/drivers/usb/nomadik/nomadik_udc.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/usb/nomadik/nomadik_udc.h 2008-09-17 13:23:34.000000000 +0530 @@ -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; + diff -Nauprw linux-2.6.20/drivers/usb/nomadik/otg_func.c ../new/linux-2.6.20/drivers/usb/nomadik/otg_func.c --- linux-2.6.20/drivers/usb/nomadik/otg_func.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/usb/nomadik/otg_func.c 2008-09-17 13:23:34.000000000 +0530 @@ -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) +{ + +} + + + + diff -Nauprw linux-2.6.20/drivers/usb/nomadik/otg_pwm.c ../new/linux-2.6.20/drivers/usb/nomadik/otg_pwm.c --- linux-2.6.20/drivers/usb/nomadik/otg_pwm.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/usb/nomadik/otg_pwm.c 2008-08-08 19:15:35.000000000 +0530 @@ -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(); +} diff -Nauprw linux-2.6.20/drivers/usb/nomadik/plat_arc.h ../new/linux-2.6.20/drivers/usb/nomadik/plat_arc.h --- linux-2.6.20/drivers/usb/nomadik/plat_arc.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/usb/nomadik/plat_arc.h 2008-07-28 15:21:12.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/plat_cnf.h ../new/linux-2.6.20/drivers/usb/nomadik/plat_cnf.h --- linux-2.6.20/drivers/usb/nomadik/plat_cnf.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/usb/nomadik/plat_cnf.h 2008-08-08 19:15:36.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/video/amba-clcd.c ../new/linux-2.6.20/drivers/video/amba-clcd.c --- linux-2.6.20/drivers/video/amba-clcd.c 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/drivers/video/amba-clcd.c 2008-11-19 16:47:04.000000000 +0530 @@ -9,6 +9,10 @@ * 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 @@ -24,18 +28,28 @@ #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()) { @@ -117,6 +131,7 @@ clcdfb_set_bitfields(struct clcd_fb *fb, 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; @@ -140,9 +155,12 @@ clcdfb_set_bitfields(struct clcd_fb *fb, * 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; @@ -161,14 +179,23 @@ clcdfb_set_bitfields(struct clcd_fb *fb, * 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; } } @@ -207,6 +234,7 @@ static int clcdfb_set_par(struct fb_info else fb->fb.fix.visual = FB_VISUAL_TRUECOLOR; + fb->board->decode(fb, ®s); clcdfb_disable(fb); @@ -244,10 +272,6 @@ static inline u32 convert_bitfield(int v 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) @@ -263,11 +287,19 @@ clcdfb_setcolreg(unsigned int regno, uns 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. @@ -282,14 +314,24 @@ clcdfb_setcolreg(unsigned int regno, uns 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 @@ -298,7 +340,8 @@ clcdfb_setcolreg(unsigned int regno, uns * 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); @@ -311,8 +354,7 @@ static int clcdfb_blank(int blank_mode, 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; @@ -363,7 +405,7 @@ static int clcdfb_register(struct clcd_f 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; @@ -432,6 +474,26 @@ static int clcdfb_register(struct clcd_f 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; @@ -449,7 +511,8 @@ static int clcdfb_probe(struct amba_devi 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; } @@ -481,6 +544,7 @@ static int clcdfb_remove(struct amba_dev { struct clcd_fb *fb = amba_get_drvdata(dev); + amba_set_drvdata(dev, NULL); clcdfb_disable(fb); @@ -499,8 +563,8 @@ static int clcdfb_remove(struct amba_dev static struct amba_id clcdfb_id_table[] = { { - .id = 0x00041110, - .mask = 0x000ffffe, + .id = CLCD_PER_ID, + .mask = CLCD_PER_MASK, }, { 0, 0 }, }; @@ -512,6 +576,11 @@ static struct amba_driver clcd_driver = .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) diff -Nauprw linux-2.6.20/drivers/video/fbmem.c ../new/linux-2.6.20/drivers/video/fbmem.c --- linux-2.6.20/drivers/video/fbmem.c 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/drivers/video/fbmem.c 2007-11-21 11:51:41.000000000 +0530 @@ -234,7 +234,6 @@ static void fb_set_logo_directpalette(st { int redshift, greenshift, blueshift; int i; - redshift = info->var.red.offset; greenshift = info->var.green.offset; blueshift = info->var.blue.offset; diff -Nauprw linux-2.6.20/drivers/video/Makefile ../new/linux-2.6.20/drivers/video/Makefile --- linux-2.6.20/drivers/video/Makefile 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/drivers/video/Makefile 2007-11-21 11:51:42.000000000 +0530 @@ -30,6 +30,7 @@ obj-$(CONFIG_FB_CYBER2000) += cyb 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/ diff -Nauprw linux-2.6.20/drivers/video/nomadik/hcl/debug.h ../new/linux-2.6.20/drivers/video/nomadik/hcl/debug.h --- linux-2.6.20/drivers/video/nomadik/hcl/debug.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/video/nomadik/hcl/debug.h 2007-11-21 11:51:42.000000000 +0530 @@ -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 */ + + diff -Nauprw linux-2.6.20/drivers/video/nomadik/hcl/hcl_defs.h ../new/linux-2.6.20/drivers/video/nomadik/hcl/hcl_defs.h --- linux-2.6.20/drivers/video/nomadik/hcl/hcl_defs.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/video/nomadik/hcl/hcl_defs.h 2007-11-21 11:51:42.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/video/nomadik/hcl/platform_os.h ../new/linux-2.6.20/drivers/video/nomadik/hcl/platform_os.h --- linux-2.6.20/drivers/video/nomadik/hcl/platform_os.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/video/nomadik/hcl/platform_os.h 2007-11-21 11:51:42.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/video/nomadik/hcl/sga.c ../new/linux-2.6.20/drivers/video/nomadik/hcl/sga.c --- linux-2.6.20/drivers/video/nomadik/hcl/sga.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/video/nomadik/hcl/sga.c 2008-10-06 12:06:22.000000000 +0530 @@ -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); +} diff -Nauprw linux-2.6.20/drivers/video/nomadik/hcl/sga.h ../new/linux-2.6.20/drivers/video/nomadik/hcl/sga.h --- linux-2.6.20/drivers/video/nomadik/hcl/sga.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/video/nomadik/hcl/sga.h 2008-10-06 12:06:22.000000000 +0530 @@ -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_ */ diff -Nauprw linux-2.6.20/drivers/video/nomadik/hcl/sga_irq.c ../new/linux-2.6.20/drivers/video/nomadik/hcl/sga_irq.c --- linux-2.6.20/drivers/video/nomadik/hcl/sga_irq.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/video/nomadik/hcl/sga_irq.c 2007-11-21 11:51:42.000000000 +0530 @@ -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); + } + } +} diff -Nauprw linux-2.6.20/drivers/video/nomadik/hcl/sga_irq.h ../new/linux-2.6.20/drivers/video/nomadik/hcl/sga_irq.h --- linux-2.6.20/drivers/video/nomadik/hcl/sga_irq.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/video/nomadik/hcl/sga_irq.h 2007-11-21 11:51:42.000000000 +0530 @@ -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_ */ diff -Nauprw linux-2.6.20/drivers/video/nomadik/hcl/sga_irqp.h ../new/linux-2.6.20/drivers/video/nomadik/hcl/sga_irqp.h --- linux-2.6.20/drivers/video/nomadik/hcl/sga_irqp.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/video/nomadik/hcl/sga_irqp.h 2007-11-21 11:51:42.000000000 +0530 @@ -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 */ + diff -Nauprw linux-2.6.20/drivers/video/nomadik/hcl/sga_p.h ../new/linux-2.6.20/drivers/video/nomadik/hcl/sga_p.h --- linux-2.6.20/drivers/video/nomadik/hcl/sga_p.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/video/nomadik/hcl/sga_p.h 2007-11-21 11:51:42.000000000 +0530 @@ -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_ */ + diff -Nauprw linux-2.6.20/drivers/video/nomadik/Makefile ../new/linux-2.6.20/drivers/video/nomadik/Makefile --- linux-2.6.20/drivers/video/nomadik/Makefile 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/video/nomadik/Makefile 2007-11-21 11:51:42.000000000 +0530 @@ -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) diff -Nauprw linux-2.6.20/drivers/video/nomadik/sga_defs.h ../new/linux-2.6.20/drivers/video/nomadik/sga_defs.h --- linux-2.6.20/drivers/video/nomadik/sga_defs.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/video/nomadik/sga_defs.h 2008-10-06 12:06:23.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/video/nomadik/sga_err.h ../new/linux-2.6.20/drivers/video/nomadik/sga_err.h --- linux-2.6.20/drivers/video/nomadik/sga_err.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/video/nomadik/sga_err.h 2007-11-21 11:51:42.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/video/nomadik/sga_interface.h ../new/linux-2.6.20/drivers/video/nomadik/sga_interface.h --- linux-2.6.20/drivers/video/nomadik/sga_interface.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/video/nomadik/sga_interface.h 2008-10-06 12:06:23.000000000 +0530 @@ -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__ + diff -Nauprw linux-2.6.20/drivers/video/nomadik/sga_ioctlfns.c ../new/linux-2.6.20/drivers/video/nomadik/sga_ioctlfns.c --- linux-2.6.20/drivers/video/nomadik/sga_ioctlfns.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/video/nomadik/sga_ioctlfns.c 2008-11-24 14:06:27.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/drivers/video/nomadik/sga_ioctlfns.h ../new/linux-2.6.20/drivers/video/nomadik/sga_ioctlfns.h --- linux-2.6.20/drivers/video/nomadik/sga_ioctlfns.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/video/nomadik/sga_ioctlfns.h 2007-11-21 11:51:42.000000000 +0530 @@ -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 + diff -Nauprw linux-2.6.20/drivers/video/nomadik/sga_main.c ../new/linux-2.6.20/drivers/video/nomadik/sga_main.c --- linux-2.6.20/drivers/video/nomadik/sga_main.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/video/nomadik/sga_main.c 2008-11-24 14:06:27.000000000 +0530 @@ -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); + diff -Nauprw linux-2.6.20/drivers/video/nomadik/sga_main.h ../new/linux-2.6.20/drivers/video/nomadik/sga_main.h --- linux-2.6.20/drivers/video/nomadik/sga_main.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/video/nomadik/sga_main.h 2007-11-21 11:51:42.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/drivers/video/nomadik/sga_typs.h ../new/linux-2.6.20/drivers/video/nomadik/sga_typs.h --- linux-2.6.20/drivers/video/nomadik/sga_typs.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/drivers/video/nomadik/sga_typs.h 2007-11-21 11:51:42.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/fs/Kconfig ../new/linux-2.6.20/fs/Kconfig --- linux-2.6.20/fs/Kconfig 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/fs/Kconfig 2008-09-17 13:23:34.000000000 +0530 @@ -1196,6 +1196,10 @@ config EFS_FS 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 diff -Nauprw linux-2.6.20/fs/Makefile ../new/linux-2.6.20/fs/Makefile --- linux-2.6.20/fs/Makefile 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/fs/Makefile 2008-09-17 13:23:34.000000000 +0530 @@ -115,3 +115,6 @@ 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/ diff -Nauprw linux-2.6.20/fs/proc/proc_misc.c ../new/linux-2.6.20/fs/proc/proc_misc.c --- linux-2.6.20/fs/proc/proc_misc.c 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/fs/proc/proc_misc.c 2008-07-04 23:45:24.000000000 +0530 @@ -65,6 +65,7 @@ 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); @@ -612,6 +613,29 @@ static int filesystems_read_proc(char *p 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) { @@ -687,11 +711,19 @@ void __init proc_misc_init(void) #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); diff -Nauprw linux-2.6.20/fs/yaffs2/devextras.h ../new/linux-2.6.20/fs/yaffs2/devextras.h --- linux-2.6.20/fs/yaffs2/devextras.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/fs/yaffs2/devextras.h 2008-09-12 12:54:02.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/fs/yaffs2/Kconfig ../new/linux-2.6.20/fs/yaffs2/Kconfig --- linux-2.6.20/fs/yaffs2/Kconfig 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/fs/yaffs2/Kconfig 2008-09-12 12:54:02.000000000 +0530 @@ -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. diff -Nauprw linux-2.6.20/fs/yaffs2/Makefile ../new/linux-2.6.20/fs/yaffs2/Makefile --- linux-2.6.20/fs/yaffs2/Makefile 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/fs/yaffs2/Makefile 2008-09-12 12:54:02.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/fs/yaffs2/moduleconfig.h ../new/linux-2.6.20/fs/yaffs2/moduleconfig.h --- linux-2.6.20/fs/yaffs2/moduleconfig.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/fs/yaffs2/moduleconfig.h 2008-09-12 12:54:02.000000000 +0530 @@ -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__ */ diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_checkptrw.c ../new/linux-2.6.20/fs/yaffs2/yaffs_checkptrw.c --- linux-2.6.20/fs/yaffs2/yaffs_checkptrw.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/fs/yaffs2/yaffs_checkptrw.c 2008-09-12 12:54:02.000000000 +0530 @@ -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); +} + + + diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_checkptrw.h ../new/linux-2.6.20/fs/yaffs2/yaffs_checkptrw.h --- linux-2.6.20/fs/yaffs2/yaffs_checkptrw.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/fs/yaffs2/yaffs_checkptrw.h 2008-09-12 12:54:02.000000000 +0530 @@ -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 + diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_ecc.c ../new/linux-2.6.20/fs/yaffs2/yaffs_ecc.c --- linux-2.6.20/fs/yaffs2/yaffs_ecc.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/fs/yaffs2/yaffs_ecc.c 2008-09-12 12:54:02.000000000 +0530 @@ -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; + +} + diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_ecc.h ../new/linux-2.6.20/fs/yaffs2/yaffs_ecc.h --- linux-2.6.20/fs/yaffs2/yaffs_ecc.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/fs/yaffs2/yaffs_ecc.h 2008-09-12 12:54:02.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_fs.c ../new/linux-2.6.20/fs/yaffs2/yaffs_fs.c --- linux-2.6.20/fs/yaffs2/yaffs_fs.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/fs/yaffs2/yaffs_fs.c 2008-09-12 12:54:02.000000000 +0530 @@ -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"); diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_guts.c ../new/linux-2.6.20/fs/yaffs2/yaffs_guts.c --- linux-2.6.20/fs/yaffs2/yaffs_guts.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/fs/yaffs2/yaffs_guts.c 2008-09-12 12:54:03.000000000 +0530 @@ -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; +} diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_guts.h ../new/linux-2.6.20/fs/yaffs2/yaffs_guts.h --- linux-2.6.20/fs/yaffs2/yaffs_guts.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/fs/yaffs2/yaffs_guts.h 2008-09-12 12:54:03.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/fs/yaffs2/yaffsinterface.h ../new/linux-2.6.20/fs/yaffs2/yaffsinterface.h --- linux-2.6.20/fs/yaffs2/yaffsinterface.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/fs/yaffs2/yaffsinterface.h 2008-09-12 12:54:05.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_mtdif1.c ../new/linux-2.6.20/fs/yaffs2/yaffs_mtdif1.c --- linux-2.6.20/fs/yaffs2/yaffs_mtdif1.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/fs/yaffs2/yaffs_mtdif1.c 2008-09-12 12:54:03.000000000 +0530 @@ -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*/ diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_mtdif1.h ../new/linux-2.6.20/fs/yaffs2/yaffs_mtdif1.h --- linux-2.6.20/fs/yaffs2/yaffs_mtdif1.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/fs/yaffs2/yaffs_mtdif1.h 2008-09-12 12:54:03.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_mtdif2.c ../new/linux-2.6.20/fs/yaffs2/yaffs_mtdif2.c --- linux-2.6.20/fs/yaffs2/yaffs_mtdif2.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/fs/yaffs2/yaffs_mtdif2.c 2008-09-12 12:54:03.000000000 +0530 @@ -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; +} + diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_mtdif2.h ../new/linux-2.6.20/fs/yaffs2/yaffs_mtdif2.h --- linux-2.6.20/fs/yaffs2/yaffs_mtdif2.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/fs/yaffs2/yaffs_mtdif2.h 2008-09-12 12:54:03.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_mtdif.c ../new/linux-2.6.20/fs/yaffs2/yaffs_mtdif.c --- linux-2.6.20/fs/yaffs2/yaffs_mtdif.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/fs/yaffs2/yaffs_mtdif.c 2008-09-12 12:54:03.000000000 +0530 @@ -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; +} + diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_mtdif.h ../new/linux-2.6.20/fs/yaffs2/yaffs_mtdif.h --- linux-2.6.20/fs/yaffs2/yaffs_mtdif.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/fs/yaffs2/yaffs_mtdif.h 2008-09-12 12:54:03.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_nand.c ../new/linux-2.6.20/fs/yaffs2/yaffs_nand.c --- linux-2.6.20/fs/yaffs2/yaffs_nand.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/fs/yaffs2/yaffs_nand.c 2008-09-12 12:54:03.000000000 +0530 @@ -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); +} + + + diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_nandemul2k.h ../new/linux-2.6.20/fs/yaffs2/yaffs_nandemul2k.h --- linux-2.6.20/fs/yaffs2/yaffs_nandemul2k.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/fs/yaffs2/yaffs_nandemul2k.h 2008-09-12 12:54:04.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_nand.h ../new/linux-2.6.20/fs/yaffs2/yaffs_nand.h --- linux-2.6.20/fs/yaffs2/yaffs_nand.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/fs/yaffs2/yaffs_nand.h 2008-09-12 12:54:03.000000000 +0530 @@ -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 + diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_packedtags1.c ../new/linux-2.6.20/fs/yaffs2/yaffs_packedtags1.c --- linux-2.6.20/fs/yaffs2/yaffs_packedtags1.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/fs/yaffs2/yaffs_packedtags1.c 2008-09-12 12:54:04.000000000 +0530 @@ -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)); + + } +} diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_packedtags1.h ../new/linux-2.6.20/fs/yaffs2/yaffs_packedtags1.h --- linux-2.6.20/fs/yaffs2/yaffs_packedtags1.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/fs/yaffs2/yaffs_packedtags1.h 2008-09-12 12:54:04.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_packedtags2.c ../new/linux-2.6.20/fs/yaffs2/yaffs_packedtags2.c --- linux-2.6.20/fs/yaffs2/yaffs_packedtags2.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/fs/yaffs2/yaffs_packedtags2.c 2008-09-12 12:54:04.000000000 +0530 @@ -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); + +} diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_packedtags2.h ../new/linux-2.6.20/fs/yaffs2/yaffs_packedtags2.h --- linux-2.6.20/fs/yaffs2/yaffs_packedtags2.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/fs/yaffs2/yaffs_packedtags2.h 2008-09-12 12:54:04.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_qsort.c ../new/linux-2.6.20/fs/yaffs2/yaffs_qsort.c --- linux-2.6.20/fs/yaffs2/yaffs_qsort.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/fs/yaffs2/yaffs_qsort.c 2008-09-12 12:54:04.000000000 +0530 @@ -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);*/ +} diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_qsort.h ../new/linux-2.6.20/fs/yaffs2/yaffs_qsort.h --- linux-2.6.20/fs/yaffs2/yaffs_qsort.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/fs/yaffs2/yaffs_qsort.h 2008-09-12 12:54:04.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_tagscompat.c ../new/linux-2.6.20/fs/yaffs2/yaffs_tagscompat.c --- linux-2.6.20/fs/yaffs2/yaffs_tagscompat.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/fs/yaffs2/yaffs_tagscompat.c 2008-09-12 12:54:04.000000000 +0530 @@ -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; +} diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_tagscompat.h ../new/linux-2.6.20/fs/yaffs2/yaffs_tagscompat.h --- linux-2.6.20/fs/yaffs2/yaffs_tagscompat.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/fs/yaffs2/yaffs_tagscompat.h 2008-09-12 12:54:04.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_tagsvalidity.c ../new/linux-2.6.20/fs/yaffs2/yaffs_tagsvalidity.c --- linux-2.6.20/fs/yaffs2/yaffs_tagsvalidity.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/fs/yaffs2/yaffs_tagsvalidity.c 2008-09-12 12:54:04.000000000 +0530 @@ -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); + +} diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_tagsvalidity.h ../new/linux-2.6.20/fs/yaffs2/yaffs_tagsvalidity.h --- linux-2.6.20/fs/yaffs2/yaffs_tagsvalidity.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/fs/yaffs2/yaffs_tagsvalidity.h 2008-09-12 12:54:05.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/fs/yaffs2/yportenv.h ../new/linux-2.6.20/fs/yaffs2/yportenv.h --- linux-2.6.20/fs/yaffs2/yportenv.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/fs/yaffs2/yportenv.h 2008-09-12 12:54:05.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/.gitignore ../new/linux-2.6.20/.gitignore --- linux-2.6.20/.gitignore 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/.gitignore 1970-01-01 05:30:00.000000000 +0530 @@ -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.* diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/audiocodec.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/audiocodec.h --- linux-2.6.20/include/asm-arm/arch-nomadik/audiocodec.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/audiocodec.h 2008-11-24 14:06:27.000000000 +0530 @@ -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*/ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/bits.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/bits.h --- linux-2.6.20/include/asm-arm/arch-nomadik/bits.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/bits.h 2007-11-21 11:51:41.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/debug.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/debug.h --- linux-2.6.20/include/asm-arm/arch-nomadik/debug.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/debug.h 2007-11-21 11:51:41.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/debug-macro.S ../new/linux-2.6.20/include/asm-arm/arch-nomadik/debug-macro.S --- linux-2.6.20/include/asm-arm/arch-nomadik/debug-macro.S 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/debug-macro.S 2007-11-21 11:51:41.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/defs.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/defs.h --- linux-2.6.20/include/asm-arm/arch-nomadik/defs.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/defs.h 2007-11-21 11:51:41.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/dma.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/dma.h --- linux-2.6.20/include/asm-arm/arch-nomadik/dma.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/dma.h 2007-11-21 11:51:41.000000000 +0530 @@ -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 */ + diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/entry-macro.S ../new/linux-2.6.20/include/asm-arm/arch-nomadik/entry-macro.S --- linux-2.6.20/include/asm-arm/arch-nomadik/entry-macro.S 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/entry-macro.S 2008-07-04 23:45:25.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/epio.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/epio.h --- linux-2.6.20/include/asm-arm/arch-nomadik/epio.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/epio.h 2007-11-21 11:51:41.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/fsmc.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/fsmc.h --- linux-2.6.20/include/asm-arm/arch-nomadik/fsmc.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/fsmc.h 2008-09-17 13:23:35.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/gpio.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/gpio.h --- linux-2.6.20/include/asm-arm/arch-nomadik/gpio.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/gpio.h 2008-09-17 13:23:35.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/hardware.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/hardware.h --- linux-2.6.20/include/asm-arm/arch-nomadik/hardware.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/hardware.h 2008-09-17 13:23:35.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/i2c.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/i2c.h --- linux-2.6.20/include/asm-arm/arch-nomadik/i2c.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/i2c.h 2007-11-21 11:51:41.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/io.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/io.h --- linux-2.6.20/include/asm-arm/arch-nomadik/io.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/io.h 2007-11-21 11:51:41.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/irqs.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/irqs.h --- linux-2.6.20/include/asm-arm/arch-nomadik/irqs.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/irqs.h 2007-11-21 11:51:41.000000000 +0530 @@ -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*/ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/memory.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/memory.h --- linux-2.6.20/include/asm-arm/arch-nomadik/memory.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/memory.h 2007-11-21 11:51:42.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/mmc.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/mmc.h --- linux-2.6.20/include/asm-arm/arch-nomadik/mmc.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/mmc.h 2007-11-21 11:51:42.000000000 +0530 @@ -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); +}; + + diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/msp.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/msp.h --- linux-2.6.20/include/asm-arm/arch-nomadik/msp.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/msp.h 2008-11-19 16:47:04.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/msp-spi.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/msp-spi.h --- linux-2.6.20/include/asm-arm/arch-nomadik/msp-spi.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/msp-spi.h 2007-11-21 11:51:42.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/mtu.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/mtu.h --- linux-2.6.20/include/asm-arm/arch-nomadik/mtu.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/mtu.h 2007-11-21 11:51:42.000000000 +0530 @@ -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); diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/nandflash.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/nandflash.h --- linux-2.6.20/include/asm-arm/arch-nomadik/nandflash.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/nandflash.h 2007-11-21 11:51:42.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/ndk10_devices.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/ndk10_devices.h --- linux-2.6.20/include/asm-arm/arch-nomadik/ndk10_devices.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/ndk10_devices.h 2007-11-21 11:51:42.000000000 +0530 @@ -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*/ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/ndk15c02_devices.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/ndk15c02_devices.h --- linux-2.6.20/include/asm-arm/arch-nomadik/ndk15c02_devices.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/ndk15c02_devices.h 2008-07-04 23:45:26.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/ndk15_devices.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/ndk15_devices.h --- linux-2.6.20/include/asm-arm/arch-nomadik/ndk15_devices.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/ndk15_devices.h 2007-11-21 11:51:42.000000000 +0530 @@ -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*/ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/nhk15_devices.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/nhk15_devices.h --- linux-2.6.20/include/asm-arm/arch-nomadik/nhk15_devices.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/nhk15_devices.h 2008-11-24 14:06:28.000000000 +0530 @@ -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*/ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/param.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/param.h --- linux-2.6.20/include/asm-arm/arch-nomadik/param.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/param.h 2007-11-21 11:51:42.000000000 +0530 @@ -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 + */ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/pexp.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/pexp.h --- linux-2.6.20/include/asm-arm/arch-nomadik/pexp.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/pexp.h 2008-07-04 23:45:27.000000000 +0530 @@ -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 + diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/power.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/power.h --- linux-2.6.20/include/asm-arm/arch-nomadik/power.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/power.h 2008-07-28 15:20:47.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/smp.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/smp.h --- linux-2.6.20/include/asm-arm/arch-nomadik/smp.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/smp.h 2007-11-21 11:51:42.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/spi.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/spi.h --- linux-2.6.20/include/asm-arm/arch-nomadik/spi.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/spi.h 2008-07-28 15:20:48.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/ssp-spi.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/ssp-spi.h --- linux-2.6.20/include/asm-arm/arch-nomadik/ssp-spi.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/ssp-spi.h 2007-11-21 11:51:42.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/stn8810_devices.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/stn8810_devices.h --- linux-2.6.20/include/asm-arm/arch-nomadik/stn8810_devices.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/stn8810_devices.h 2007-11-21 11:51:42.000000000 +0530 @@ -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_ */ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/sva.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/sva.h --- linux-2.6.20/include/asm-arm/arch-nomadik/sva.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/sva.h 2008-07-17 16:42:46.000000000 +0530 @@ -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); +}; + + diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/system.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/system.h --- linux-2.6.20/include/asm-arm/arch-nomadik/system.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/system.h 2008-07-04 23:45:29.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/timex.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/timex.h --- linux-2.6.20/include/asm-arm/arch-nomadik/timex.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/timex.h 2007-11-21 11:51:42.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/touchp2003.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/touchp2003.h --- linux-2.6.20/include/asm-arm/arch-nomadik/touchp2003.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/touchp2003.h 2007-11-21 11:51:42.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/touchp.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/touchp.h --- linux-2.6.20/include/asm-arm/arch-nomadik/touchp.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/touchp.h 2008-07-04 23:45:30.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/udc.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/udc.h --- linux-2.6.20/include/asm-arm/arch-nomadik/udc.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/udc.h 2008-07-04 23:45:53.000000000 +0530 @@ -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) + + diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/uncompress.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/uncompress.h --- linux-2.6.20/include/asm-arm/arch-nomadik/uncompress.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/uncompress.h 2007-11-21 11:51:42.000000000 +0530 @@ -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() diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/vmalloc.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/vmalloc.h --- linux-2.6.20/include/asm-arm/arch-nomadik/vmalloc.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/vmalloc.h 2007-11-21 11:51:42.000000000 +0530 @@ -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) diff -Nauprw linux-2.6.20/include/asm-arm/kgdb.h ../new/linux-2.6.20/include/asm-arm/kgdb.h --- linux-2.6.20/include/asm-arm/kgdb.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/include/asm-arm/kgdb.h 2007-11-21 11:51:42.000000000 +0530 @@ -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__ */ diff -Nauprw linux-2.6.20/include/asm-arm/system.h ../new/linux-2.6.20/include/asm-arm/system.h --- linux-2.6.20/include/asm-arm/system.h 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/include/asm-arm/system.h 2007-11-21 11:51:42.000000000 +0530 @@ -345,6 +345,47 @@ 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) diff -Nauprw linux-2.6.20/include/asm-generic/kgdb.h ../new/linux-2.6.20/include/asm-generic/kgdb.h --- linux-2.6.20/include/asm-generic/kgdb.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/include/asm-generic/kgdb.h 2007-11-21 11:51:42.000000000 +0530 @@ -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__ */ diff -Nauprw linux-2.6.20/include/linux/amba/clcd.h ../new/linux-2.6.20/include/linux/amba/clcd.h --- linux-2.6.20/include/linux/amba/clcd.h 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/include/linux/amba/clcd.h 2007-11-21 11:51:42.000000000 +0530 @@ -53,7 +53,12 @@ #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) @@ -66,6 +71,13 @@ #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; @@ -218,8 +230,20 @@ static inline void clcdfb_decode(struct 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; diff -Nauprw linux-2.6.20/include/linux/dwarf2.h ../new/linux-2.6.20/include/linux/dwarf2.h --- linux-2.6.20/include/linux/dwarf2.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/include/linux/dwarf2.h 2007-11-21 11:51:42.000000000 +0530 @@ -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 */ diff -Nauprw linux-2.6.20/include/linux/dwarf2-lang.h ../new/linux-2.6.20/include/linux/dwarf2-lang.h --- linux-2.6.20/include/linux/dwarf2-lang.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/include/linux/dwarf2-lang.h 2007-11-21 11:51:42.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/include/linux/i2c.h ../new/linux-2.6.20/include/linux/i2c.h --- linux-2.6.20/include/linux/i2c.h 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/include/linux/i2c.h 2007-11-21 11:51:42.000000000 +0530 @@ -146,6 +146,9 @@ struct i2c_driver { 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 */ @@ -214,8 +217,18 @@ struct i2c_adapter { /* --- 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; diff -Nauprw linux-2.6.20/include/linux/kgdb.h ../new/linux-2.6.20/include/linux/kgdb.h --- linux-2.6.20/include/linux/kgdb.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/include/linux/kgdb.h 2007-11-21 11:51:42.000000000 +0530 @@ -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__ */ diff -Nauprw linux-2.6.20/include/linux/miscdevice.h ../new/linux-2.6.20/include/linux/miscdevice.h --- linux-2.6.20/include/linux/miscdevice.h 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/include/linux/miscdevice.h 2007-11-21 11:51:42.000000000 +0530 @@ -12,6 +12,7 @@ #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 diff -Nauprw linux-2.6.20/include/linux/module.h ../new/linux-2.6.20/include/linux/module.h --- linux-2.6.20/include/linux/module.h 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/include/linux/module.h 2008-10-20 13:37:45.000000000 +0530 @@ -34,6 +34,9 @@ struct kernel_symbol { unsigned long value; const char *name; +#ifdef CONFIG_LKM_HASH + unsigned long hash_value; +#endif }; struct modversion_info @@ -186,6 +189,13 @@ void *__symbol_get_gpl(const char *symbo #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; \ @@ -196,7 +206,7 @@ void *__symbol_get_gpl(const char *symbo 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, "") @@ -228,8 +238,17 @@ 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 { @@ -257,6 +276,13 @@ struct module /* 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; diff -Nauprw linux-2.6.20/include/linux/mtd/bbm.h ../new/linux-2.6.20/include/linux/mtd/bbm.h --- linux-2.6.20/include/linux/mtd/bbm.h 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/include/linux/mtd/bbm.h 2008-09-17 13:23:35.000000000 +0530 @@ -10,6 +10,10 @@ * 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 @@ -92,6 +96,13 @@ struct nand_bbt_descr { */ #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 diff -Nauprw linux-2.6.20/include/linux/mtd/mtd.h ../new/linux-2.6.20/include/linux/mtd/mtd.h --- linux-2.6.20/include/linux/mtd/mtd.h 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/include/linux/mtd/mtd.h 2008-11-19 16:47:04.000000000 +0530 @@ -119,6 +119,7 @@ struct mtd_info { 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 diff -Nauprw linux-2.6.20/include/linux/mtd/nand.h ../new/linux-2.6.20/include/linux/mtd/nand.h --- linux-2.6.20/include/linux/mtd/nand.h 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/include/linux/mtd/nand.h 2007-11-21 11:51:42.000000000 +0530 @@ -546,54 +546,12 @@ extern int nand_do_read(struct mtd_info /* * 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 */ diff -Nauprw linux-2.6.20/include/linux/mtd/onenand.h ../new/linux-2.6.20/include/linux/mtd/onenand.h --- linux-2.6.20/include/linux/mtd/onenand.h 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/include/linux/mtd/onenand.h 2008-09-17 13:23:35.000000000 +0530 @@ -42,14 +42,10 @@ typedef enum { /** * 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; }; /** @@ -63,8 +59,8 @@ struct onenand_bufferram { * 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 @@ -87,7 +83,8 @@ struct onenand_bufferram { * @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 @@ -103,8 +100,8 @@ struct onenand_chip { 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]; @@ -128,6 +125,7 @@ struct onenand_chip { wait_queue_head_t wq; onenand_state_t state; unsigned char *page_buf; + unsigned char *oob_buf; int subpagesize; struct nand_ecclayout *ecclayout; @@ -144,12 +142,24 @@ struct onenand_chip { #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) @@ -158,7 +168,9 @@ struct onenand_chip { */ #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 @@ -176,3 +188,4 @@ struct onenand_manufacturers { }; #endif /* __LINUX_MTD_ONENAND_H */ + diff -Nauprw linux-2.6.20/include/linux/mtd/onenand_regs.h ../new/linux-2.6.20/include/linux/mtd/onenand_regs.h --- linux-2.6.20/include/linux/mtd/onenand_regs.h 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/include/linux/mtd/onenand_regs.h 2008-09-17 13:23:35.000000000 +0530 @@ -73,6 +73,8 @@ #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) @@ -80,9 +82,11 @@ #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) @@ -108,6 +112,8 @@ #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) diff -Nauprw linux-2.6.20/include/linux/netpoll.h ../new/linux-2.6.20/include/linux/netpoll.h --- linux-2.6.20/include/linux/netpoll.h 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/include/linux/netpoll.h 2007-11-21 11:51:42.000000000 +0530 @@ -16,7 +16,7 @@ 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; diff -Nauprw linux-2.6.20/include/linux/usb.h ../new/linux-2.6.20/include/linux/usb.h --- linux-2.6.20/include/linux/usb.h 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/include/linux/usb.h 2008-07-04 23:45:30.000000000 +0530 @@ -287,7 +287,9 @@ struct usb_bus { 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? diff -Nauprw linux-2.6.20/include/linux/v4l2-nomadikdefs.h ../new/linux-2.6.20/include/linux/v4l2-nomadikdefs.h --- linux-2.6.20/include/linux/v4l2-nomadikdefs.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/include/linux/v4l2-nomadikdefs.h 2008-11-24 14:06:28.000000000 +0530 @@ -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) + diff -Nauprw linux-2.6.20/include/linux/videodev2.h ../new/linux-2.6.20/include/linux/videodev2.h --- linux-2.6.20/include/linux/videodev2.h 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/include/linux/videodev2.h 2008-11-24 14:06:28.000000000 +0530 @@ -1340,6 +1340,17 @@ struct v4l2_streamparm #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) diff -Nauprw linux-2.6.20/init/Kconfig ../new/linux-2.6.20/init/Kconfig --- linux-2.6.20/init/Kconfig 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/init/Kconfig 2008-10-20 13:37:46.000000000 +0530 @@ -561,6 +561,21 @@ config KMOD 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 diff -Nauprw linux-2.6.20/kernel/kgdb.c ../new/linux-2.6.20/kernel/kgdb.c --- linux-2.6.20/kernel/kgdb.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/kernel/kgdb.c 2008-10-20 13:37:46.000000000 +0530 @@ -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); diff -Nauprw linux-2.6.20/kernel/Makefile ../new/linux-2.6.20/kernel/Makefile --- linux-2.6.20/kernel/Makefile 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/kernel/Makefile 2007-11-21 11:51:42.000000000 +0530 @@ -41,6 +41,7 @@ obj-$(CONFIG_STOP_MACHINE) += stop_machi 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/ diff -Nauprw linux-2.6.20/kernel/module.c ../new/linux-2.6.20/kernel/module.c --- linux-2.6.20/kernel/module.c 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/kernel/module.c 2008-10-20 13:37:46.000000000 +0530 @@ -55,6 +55,27 @@ #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)) @@ -64,6 +85,7 @@ 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); @@ -145,7 +167,58 @@ extern const unsigned long __start___kcr #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) @@ -157,6 +230,9 @@ static const struct kernel_symbol *looku return NULL; } +#endif + + static void printk_unused_warning(const char *name) { printk(KERN_WARNING "Symbol %s is marked as UNUSED, " @@ -169,7 +245,7 @@ static void printk_unused_warning(const } /* 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) @@ -179,13 +255,13 @@ static unsigned long __find_symbol(const /* 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, @@ -193,7 +269,7 @@ static unsigned long __find_symbol(const 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) { @@ -210,7 +286,7 @@ static unsigned long __find_symbol(const 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); @@ -220,7 +296,7 @@ static unsigned long __find_symbol(const } 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); @@ -232,14 +308,14 @@ 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, @@ -247,7 +323,7 @@ static unsigned long __find_symbol(const 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)); @@ -255,7 +331,7 @@ static unsigned long __find_symbol(const } 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); @@ -264,7 +340,7 @@ static unsigned long __find_symbol(const 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) { @@ -706,6 +782,12 @@ sys_delete_module(const char __user *nam 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); @@ -718,6 +800,11 @@ sys_delete_module(const char __user *nam } 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; @@ -758,7 +845,7 @@ void __symbol_put(const char *symbol) 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); @@ -839,6 +926,9 @@ static ssize_t show_initstate(struct mod case MODULE_STATE_GOING: state = "going"; break; + case MODULE_STATE_GONE: + state = "gone"; + break; } return sprintf(buffer, "%s\n", state); } @@ -905,7 +995,7 @@ static inline int check_modstruct_versio 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); @@ -946,13 +1036,14 @@ static inline int same_magic(const char 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 */ @@ -1192,6 +1283,11 @@ static void free_module(struct module *m /* Arch-specific cleanup. */ module_arch_cleanup(mod); +#ifdef CONFIG_KGDB + /* kgdb info */ + vfree(mod->mod_sections); +#endif + /* Module unload stuff */ module_unload_free(mod); @@ -1215,7 +1311,7 @@ void *__symbol_get(const char *symbol) 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); @@ -1236,14 +1332,14 @@ static int verify_export_symbols(struct 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; @@ -1260,6 +1356,7 @@ 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, @@ -1270,6 +1367,14 @@ static int simplify_symbols(Elf_Shdr *se 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: @@ -1290,7 +1395,7 @@ static int simplify_symbols(Elf_Shdr *se 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) @@ -1451,13 +1556,39 @@ static void setup_modinfo(struct module } } +#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; @@ -1543,6 +1674,9 @@ static struct module *load_module(void _ 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; @@ -1565,6 +1699,9 @@ static struct module *load_module(void _ 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", @@ -1637,6 +1774,17 @@ static struct module *load_module(void _ 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"); @@ -1780,11 +1928,17 @@ static struct module *load_module(void _ 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; @@ -1862,6 +2016,12 @@ static struct module *load_module(void _ 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; @@ -1922,6 +2082,11 @@ static struct module *load_module(void _ 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: @@ -1993,6 +2158,11 @@ sys_init_module(void __user *umod, /* 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", diff -Nauprw linux-2.6.20/kernel/pid.c ../new/linux-2.6.20/kernel/pid.c --- linux-2.6.20/kernel/pid.c 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/kernel/pid.c 2007-11-21 11:51:42.000000000 +0530 @@ -383,8 +383,13 @@ 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; @@ -403,6 +408,10 @@ void __init pidhash_init(void) 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) diff -Nauprw linux-2.6.20/kernel/power/main.c ../new/linux-2.6.20/kernel/power/main.c --- linux-2.6.20/kernel/power/main.c 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/kernel/power/main.c 2007-11-21 11:51:42.000000000 +0530 @@ -87,7 +87,7 @@ static int suspend_prepare(suspend_state goto Thaw; } - suspend_console(); + //suspend_console(); if ((error = device_suspend(PMSG_SUSPEND))) { printk(KERN_ERR "Some devices failed to suspend\n"); goto Finish; diff -Nauprw linux-2.6.20/kernel/sched.c ../new/linux-2.6.20/kernel/sched.c --- linux-2.6.20/kernel/sched.c 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/kernel/sched.c 2007-11-21 11:51:42.000000000 +0530 @@ -52,6 +52,7 @@ #include #include #include +#include #include #include @@ -6962,6 +6963,11 @@ 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) diff -Nauprw linux-2.6.20/kernel/softlockup.c ../new/linux-2.6.20/kernel/softlockup.c --- linux-2.6.20/kernel/softlockup.c 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/kernel/softlockup.c 2007-11-21 11:51:42.000000000 +0530 @@ -13,6 +13,7 @@ #include #include #include +#include static DEFINE_SPINLOCK(print_lock); @@ -37,6 +38,9 @@ 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); diff -Nauprw linux-2.6.20/kernel/timer.c ../new/linux-2.6.20/kernel/timer.c --- linux-2.6.20/kernel/timer.c 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/kernel/timer.c 2008-10-20 13:37:46.000000000 +0530 @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -1207,8 +1208,15 @@ static inline void update_times(unsigned 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 diff -Nauprw linux-2.6.20/lib/Kconfig.debug ../new/linux-2.6.20/lib/Kconfig.debug --- linux-2.6.20/lib/Kconfig.debug 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/lib/Kconfig.debug 2007-11-21 11:51:42.000000000 +0530 @@ -429,3 +429,82 @@ config FAULT_INJECTION_DEBUG_FS 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. + diff -Nauprw linux-2.6.20/MAINTAINERS ../new/linux-2.6.20/MAINTAINERS --- linux-2.6.20/MAINTAINERS 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/MAINTAINERS 2007-11-21 11:51:42.000000000 +0530 @@ -1941,6 +1941,15 @@ 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 diff -Nauprw linux-2.6.20/Makefile ../new/linux-2.6.20/Makefile --- linux-2.6.20/Makefile 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/Makefile 2008-10-20 13:37:44.000000000 +0530 @@ -12,7 +12,7 @@ NAME = Homicidal Dwarf Hamster # 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 @@ -321,7 +321,7 @@ KERNELRELEASE = $(shell cat include/conf 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 @@ -497,7 +497,7 @@ CFLAGS += -fomit-frame-pointer endif ifdef CONFIG_DEBUG_INFO -CFLAGS += -g +CFLAGS += -gdwarf-2 endif # Force gcc to behave correct even for buggy distributions @@ -530,7 +530,6 @@ export INSTALL_PATH ?= /boot # 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 @@ -576,7 +575,7 @@ libs-y := $(libs-y1) $(libs-y2) # --------------------------------------------------------------------------- # 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 @@ -734,6 +733,7 @@ debug_kallsyms: .tmp_map$(last_kallsyms) 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 @@ -742,6 +742,7 @@ 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 @@ -1482,7 +1483,12 @@ clean := -f $(if $(KBUILD_SRC),$(srctree 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: ; diff -Nauprw linux-2.6.20/net/core/fib_rules.c ../new/linux-2.6.20/net/core/fib_rules.c --- linux-2.6.20/net/core/fib_rules.c 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/net/core/fib_rules.c 2008-08-27 04:39:17.000000000 +0530 @@ -1,473 +0,0 @@ -/* - * net/core/fib_rules.c Generic Routing Rules - * - * 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, version 2. - * - * Authors: Thomas Graf - */ - -#include -#include -#include -#include - -static LIST_HEAD(rules_ops); -static DEFINE_SPINLOCK(rules_mod_lock); - -static void notify_rule_change(int event, struct fib_rule *rule, - struct fib_rules_ops *ops, struct nlmsghdr *nlh, - u32 pid); - -static struct fib_rules_ops *lookup_rules_ops(int family) -{ - struct fib_rules_ops *ops; - - rcu_read_lock(); - list_for_each_entry_rcu(ops, &rules_ops, list) { - if (ops->family == family) { - if (!try_module_get(ops->owner)) - ops = NULL; - rcu_read_unlock(); - return ops; - } - } - rcu_read_unlock(); - - return NULL; -} - -static void rules_ops_put(struct fib_rules_ops *ops) -{ - if (ops) - module_put(ops->owner); -} - -int fib_rules_register(struct fib_rules_ops *ops) -{ - int err = -EEXIST; - struct fib_rules_ops *o; - - if (ops->rule_size < sizeof(struct fib_rule)) - return -EINVAL; - - if (ops->match == NULL || ops->configure == NULL || - ops->compare == NULL || ops->fill == NULL || - ops->action == NULL) - return -EINVAL; - - spin_lock(&rules_mod_lock); - list_for_each_entry(o, &rules_ops, list) - if (ops->family == o->family) - goto errout; - - list_add_tail_rcu(&ops->list, &rules_ops); - err = 0; -errout: - spin_unlock(&rules_mod_lock); - - return err; -} - -EXPORT_SYMBOL_GPL(fib_rules_register); - -static void cleanup_ops(struct fib_rules_ops *ops) -{ - struct fib_rule *rule, *tmp; - - list_for_each_entry_safe(rule, tmp, ops->rules_list, list) { - list_del_rcu(&rule->list); - fib_rule_put(rule); - } -} - -int fib_rules_unregister(struct fib_rules_ops *ops) -{ - int err = 0; - struct fib_rules_ops *o; - - spin_lock(&rules_mod_lock); - list_for_each_entry(o, &rules_ops, list) { - if (o == ops) { - list_del_rcu(&o->list); - cleanup_ops(ops); - goto out; - } - } - - err = -ENOENT; -out: - spin_unlock(&rules_mod_lock); - - synchronize_rcu(); - - return err; -} - -EXPORT_SYMBOL_GPL(fib_rules_unregister); - -static int fib_rule_match(struct fib_rule *rule, struct fib_rules_ops *ops, - struct flowi *fl, int flags) -{ - int ret = 0; - - if (rule->ifindex && (rule->ifindex != fl->iif)) - goto out; - - if ((rule->mark ^ fl->mark) & rule->mark_mask) - goto out; - - ret = ops->match(rule, fl, flags); -out: - return (rule->flags & FIB_RULE_INVERT) ? !ret : ret; -} - -int fib_rules_lookup(struct fib_rules_ops *ops, struct flowi *fl, - int flags, struct fib_lookup_arg *arg) -{ - struct fib_rule *rule; - int err; - - rcu_read_lock(); - - list_for_each_entry_rcu(rule, ops->rules_list, list) { - if (!fib_rule_match(rule, ops, fl, flags)) - continue; - - err = ops->action(rule, fl, flags, arg); - if (err != -EAGAIN) { - fib_rule_get(rule); - arg->rule = rule; - goto out; - } - } - - err = -ENETUNREACH; -out: - rcu_read_unlock(); - - return err; -} - -EXPORT_SYMBOL_GPL(fib_rules_lookup); - -int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) -{ - struct fib_rule_hdr *frh = nlmsg_data(nlh); - struct fib_rules_ops *ops = NULL; - struct fib_rule *rule, *r, *last = NULL; - struct nlattr *tb[FRA_MAX+1]; - int err = -EINVAL; - - if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(*frh))) - goto errout; - - ops = lookup_rules_ops(frh->family); - if (ops == NULL) { - err = EAFNOSUPPORT; - goto errout; - } - - err = nlmsg_parse(nlh, sizeof(*frh), tb, FRA_MAX, ops->policy); - if (err < 0) - goto errout; - - rule = kzalloc(ops->rule_size, GFP_KERNEL); - if (rule == NULL) { - err = -ENOMEM; - goto errout; - } - - if (tb[FRA_PRIORITY]) - rule->pref = nla_get_u32(tb[FRA_PRIORITY]); - - if (tb[FRA_IFNAME]) { - struct net_device *dev; - - rule->ifindex = -1; - nla_strlcpy(rule->ifname, tb[FRA_IFNAME], IFNAMSIZ); - dev = __dev_get_by_name(rule->ifname); - if (dev) - rule->ifindex = dev->ifindex; - } - - if (tb[FRA_FWMARK]) { - rule->mark = nla_get_u32(tb[FRA_FWMARK]); - if (rule->mark) - /* compatibility: if the mark value is non-zero all bits - * are compared unless a mask is explicitly specified. - */ - rule->mark_mask = 0xFFFFFFFF; - } - - if (tb[FRA_FWMASK]) - rule->mark_mask = nla_get_u32(tb[FRA_FWMASK]); - - rule->action = frh->action; - rule->flags = frh->flags; - rule->table = frh_get_table(frh, tb); - - if (!rule->pref && ops->default_pref) - rule->pref = ops->default_pref(); - - err = ops->configure(rule, skb, nlh, frh, tb); - if (err < 0) - goto errout_free; - - list_for_each_entry(r, ops->rules_list, list) { - if (r->pref > rule->pref) - break; - last = r; - } - - fib_rule_get(rule); - - if (last) - list_add_rcu(&rule->list, &last->list); - else - list_add_rcu(&rule->list, ops->rules_list); - - notify_rule_change(RTM_NEWRULE, rule, ops, nlh, NETLINK_CB(skb).pid); - rules_ops_put(ops); - return 0; - -errout_free: - kfree(rule); -errout: - rules_ops_put(ops); - return err; -} - -int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) -{ - struct fib_rule_hdr *frh = nlmsg_data(nlh); - struct fib_rules_ops *ops = NULL; - struct fib_rule *rule; - struct nlattr *tb[FRA_MAX+1]; - int err = -EINVAL; - - if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(*frh))) - goto errout; - - ops = lookup_rules_ops(frh->family); - if (ops == NULL) { - err = EAFNOSUPPORT; - goto errout; - } - - err = nlmsg_parse(nlh, sizeof(*frh), tb, FRA_MAX, ops->policy); - if (err < 0) - goto errout; - - list_for_each_entry(rule, ops->rules_list, list) { - if (frh->action && (frh->action != rule->action)) - continue; - - if (frh->table && (frh_get_table(frh, tb) != rule->table)) - continue; - - if (tb[FRA_PRIORITY] && - (rule->pref != nla_get_u32(tb[FRA_PRIORITY]))) - continue; - - if (tb[FRA_IFNAME] && - nla_strcmp(tb[FRA_IFNAME], rule->ifname)) - continue; - - if (tb[FRA_FWMARK] && - (rule->mark != nla_get_u32(tb[FRA_FWMARK]))) - continue; - - if (tb[FRA_FWMASK] && - (rule->mark_mask != nla_get_u32(tb[FRA_FWMASK]))) - continue; - - if (!ops->compare(rule, frh, tb)) - continue; - - if (rule->flags & FIB_RULE_PERMANENT) { - err = -EPERM; - goto errout; - } - - list_del_rcu(&rule->list); - synchronize_rcu(); - notify_rule_change(RTM_DELRULE, rule, ops, nlh, - NETLINK_CB(skb).pid); - fib_rule_put(rule); - rules_ops_put(ops); - return 0; - } - - err = -ENOENT; -errout: - rules_ops_put(ops); - return err; -} - -static inline size_t fib_rule_nlmsg_size(struct fib_rules_ops *ops, - struct fib_rule *rule) -{ - size_t payload = NLMSG_ALIGN(sizeof(struct fib_rule_hdr)) - + nla_total_size(IFNAMSIZ) /* FRA_IFNAME */ - + nla_total_size(4) /* FRA_PRIORITY */ - + nla_total_size(4) /* FRA_TABLE */ - + nla_total_size(4) /* FRA_FWMARK */ - + nla_total_size(4); /* FRA_FWMASK */ - - if (ops->nlmsg_payload) - payload += ops->nlmsg_payload(rule); - - return payload; -} - -static int fib_nl_fill_rule(struct sk_buff *skb, struct fib_rule *rule, - u32 pid, u32 seq, int type, int flags, - struct fib_rules_ops *ops) -{ - struct nlmsghdr *nlh; - struct fib_rule_hdr *frh; - - nlh = nlmsg_put(skb, pid, seq, type, sizeof(*frh), flags); - if (nlh == NULL) - return -1; - - frh = nlmsg_data(nlh); - frh->table = rule->table; - NLA_PUT_U32(skb, FRA_TABLE, rule->table); - frh->res1 = 0; - frh->res2 = 0; - frh->action = rule->action; - frh->flags = rule->flags; - - if (rule->ifname[0]) - NLA_PUT_STRING(skb, FRA_IFNAME, rule->ifname); - - if (rule->pref) - NLA_PUT_U32(skb, FRA_PRIORITY, rule->pref); - - if (rule->mark) - NLA_PUT_U32(skb, FRA_FWMARK, rule->mark); - - if (rule->mark_mask || rule->mark) - NLA_PUT_U32(skb, FRA_FWMASK, rule->mark_mask); - - if (ops->fill(rule, skb, nlh, frh) < 0) - goto nla_put_failure; - - return nlmsg_end(skb, nlh); - -nla_put_failure: - return nlmsg_cancel(skb, nlh); -} - -int fib_rules_dump(struct sk_buff *skb, struct netlink_callback *cb, int family) -{ - int idx = 0; - struct fib_rule *rule; - struct fib_rules_ops *ops; - - ops = lookup_rules_ops(family); - if (ops == NULL) - return -EAFNOSUPPORT; - - rcu_read_lock(); - list_for_each_entry(rule, ops->rules_list, list) { - if (idx < cb->args[0]) - goto skip; - - if (fib_nl_fill_rule(skb, rule, NETLINK_CB(cb->skb).pid, - cb->nlh->nlmsg_seq, RTM_NEWRULE, - NLM_F_MULTI, ops) < 0) - break; -skip: - idx++; - } - rcu_read_unlock(); - cb->args[0] = idx; - rules_ops_put(ops); - - return skb->len; -} - -EXPORT_SYMBOL_GPL(fib_rules_dump); - -static void notify_rule_change(int event, struct fib_rule *rule, - struct fib_rules_ops *ops, struct nlmsghdr *nlh, - u32 pid) -{ - struct sk_buff *skb; - int err = -ENOBUFS; - - skb = nlmsg_new(fib_rule_nlmsg_size(ops, rule), GFP_KERNEL); - if (skb == NULL) - goto errout; - - err = fib_nl_fill_rule(skb, rule, pid, nlh->nlmsg_seq, event, 0, ops); - /* failure implies BUG in fib_rule_nlmsg_size() */ - BUG_ON(err < 0); - - err = rtnl_notify(skb, pid, ops->nlgroup, nlh, GFP_KERNEL); -errout: - if (err < 0) - rtnl_set_sk_err(ops->nlgroup, err); -} - -static void attach_rules(struct list_head *rules, struct net_device *dev) -{ - struct fib_rule *rule; - - list_for_each_entry(rule, rules, list) { - if (rule->ifindex == -1 && - strcmp(dev->name, rule->ifname) == 0) - rule->ifindex = dev->ifindex; - } -} - -static void detach_rules(struct list_head *rules, struct net_device *dev) -{ - struct fib_rule *rule; - - list_for_each_entry(rule, rules, list) - if (rule->ifindex == dev->ifindex) - rule->ifindex = -1; -} - - -static int fib_rules_event(struct notifier_block *this, unsigned long event, - void *ptr) -{ - struct net_device *dev = ptr; - struct fib_rules_ops *ops; - - ASSERT_RTNL(); - rcu_read_lock(); - - switch (event) { - case NETDEV_REGISTER: - list_for_each_entry(ops, &rules_ops, list) - attach_rules(ops->rules_list, dev); - break; - - case NETDEV_UNREGISTER: - list_for_each_entry(ops, &rules_ops, list) - detach_rules(ops->rules_list, dev); - break; - } - - rcu_read_unlock(); - - return NOTIFY_DONE; -} - -static struct notifier_block fib_rules_notifier = { - .notifier_call = fib_rules_event, -}; - -static int __init fib_rules_init(void) -{ - return register_netdevice_notifier(&fib_rules_notifier); -} - -subsys_initcall(fib_rules_init); diff -Nauprw linux-2.6.20/net/core/netpoll.c ../new/linux-2.6.20/net/core/netpoll.c --- linux-2.6.20/net/core/netpoll.c 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/net/core/netpoll.c 2007-11-21 11:51:42.000000000 +0530 @@ -491,7 +491,10 @@ int __netpoll_rx(struct sk_buff *skb) 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; diff -Nauprw linux-2.6.20/net/sunrpc/xprtsock.c ../new/linux-2.6.20/net/sunrpc/xprtsock.c --- linux-2.6.20/net/sunrpc/xprtsock.c 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/net/sunrpc/xprtsock.c 2007-11-21 11:51:42.000000000 +0530 @@ -1612,8 +1612,9 @@ struct rpc_xprt *xs_setup_tcp(struct soc 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", diff -Nauprw linux-2.6.20/scripts/dwarfh.awk ../new/linux-2.6.20/scripts/dwarfh.awk --- linux-2.6.20/scripts/dwarfh.awk 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/scripts/dwarfh.awk 2007-11-21 11:51:42.000000000 +0530 @@ -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" +} diff -Nauprw linux-2.6.20/scripts/kconfig/Makefile ../new/linux-2.6.20/scripts/kconfig/Makefile --- linux-2.6.20/scripts/kconfig/Makefile 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/scripts/kconfig/Makefile 2007-11-21 11:51:42.000000000 +0530 @@ -4,22 +4,30 @@ 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 @@ -43,19 +51,19 @@ update-po-config: $(obj)/kxgettext 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 @@ -63,7 +71,7 @@ else $(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 diff -Nauprw linux-2.6.20/scripts/ksymhash/elflib.c ../new/linux-2.6.20/scripts/ksymhash/elflib.c --- linux-2.6.20/scripts/ksymhash/elflib.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/scripts/ksymhash/elflib.c 2008-10-20 13:38:35.000000000 +0530 @@ -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); +} + + diff -Nauprw linux-2.6.20/scripts/ksymhash/elflib.h ../new/linux-2.6.20/scripts/ksymhash/elflib.h --- linux-2.6.20/scripts/ksymhash/elflib.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/scripts/ksymhash/elflib.h 2008-10-20 13:38:35.000000000 +0530 @@ -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); + + diff -Nauprw linux-2.6.20/scripts/ksymhash/empty.c ../new/linux-2.6.20/scripts/ksymhash/empty.c --- linux-2.6.20/scripts/ksymhash/empty.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/scripts/ksymhash/empty.c 2008-10-20 13:38:35.000000000 +0530 @@ -0,0 +1 @@ +/* empty file to figure out endianness / word size */ diff -Nauprw linux-2.6.20/scripts/ksymhash/ksymhash.c ../new/linux-2.6.20/scripts/ksymhash/ksymhash.c --- linux-2.6.20/scripts/ksymhash/ksymhash.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/scripts/ksymhash/ksymhash.c 2008-10-20 13:38:35.000000000 +0530 @@ -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; +} diff -Nauprw linux-2.6.20/scripts/ksymhash/Makefile ../new/linux-2.6.20/scripts/ksymhash/Makefile --- linux-2.6.20/scripts/ksymhash/Makefile 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/scripts/ksymhash/Makefile 2008-10-20 13:38:35.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/scripts/ksymhash/mk_elfconfig.c ../new/linux-2.6.20/scripts/ksymhash/mk_elfconfig.c --- linux-2.6.20/scripts/ksymhash/mk_elfconfig.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/scripts/ksymhash/mk_elfconfig.c 2008-10-20 13:38:35.000000000 +0530 @@ -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; +} + diff -Nauprw linux-2.6.20/scripts/Makefile ../new/linux-2.6.20/scripts/Makefile --- linux-2.6.20/scripts/Makefile 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/scripts/Makefile 2008-10-20 13:37:46.000000000 +0530 @@ -20,6 +20,7 @@ hostprogs-y += unifdef subdir-$(CONFIG_MODVERSIONS) += genksyms subdir-y += mod +subdir-$(CONFIG_LKM_HASH) += ksymhash # Let clean descend into subdirs subdir- += basic kconfig package diff -Nauprw linux-2.6.20/scripts/Makefile.modpost ../new/linux-2.6.20/scripts/Makefile.modpost --- linux-2.6.20/scripts/Makefile.modpost 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/scripts/Makefile.modpost 2008-10-20 13:37:46.000000000 +0530 @@ -99,9 +99,11 @@ targets += $(modules:.ko=.mod.o) 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) diff -Nauprw linux-2.6.20/scripts/mod/modpost.c ../new/linux-2.6.20/scripts/mod/modpost.c --- linux-2.6.20/scripts/mod/modpost.c 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/scripts/mod/modpost.c 2008-10-20 13:37:47.000000000 +0530 @@ -1311,6 +1311,28 @@ static void add_srcversion(struct buffer } } +/** + * 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; @@ -1502,6 +1524,7 @@ int main(int argc, char **argv) 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); diff -Nauprw linux-2.6.20/sound/arm/Kconfig ../new/linux-2.6.20/sound/arm/Kconfig --- linux-2.6.20/sound/arm/Kconfig 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/sound/arm/Kconfig 2007-11-21 11:51:42.000000000 +0530 @@ -3,6 +3,17 @@ 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 diff -Nauprw linux-2.6.20/sound/arm/Makefile ../new/linux-2.6.20/sound/arm/Makefile --- linux-2.6.20/sound/arm/Makefile 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/sound/arm/Makefile 2007-11-21 11:51:42.000000000 +0530 @@ -13,3 +13,6 @@ 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 diff -Nauprw linux-2.6.20/sound/arm/nomadik_alsa.c ../new/linux-2.6.20/sound/arm/nomadik_alsa.c --- linux-2.6.20/sound/arm/nomadik_alsa.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/sound/arm/nomadik_alsa.c 2008-11-24 14:06:29.000000000 +0530 @@ -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"); diff -Nauprw linux-2.6.20/sound/arm/nomadik_alsa.h ../new/linux-2.6.20/sound/arm/nomadik_alsa.h --- linux-2.6.20/sound/arm/nomadik_alsa.h 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/sound/arm/nomadik_alsa.h 2007-11-21 11:51:42.000000000 +0530 @@ -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 diff -Nauprw linux-2.6.20/sound/Kconfig ../new/linux-2.6.20/sound/Kconfig --- linux-2.6.20/sound/Kconfig 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/sound/Kconfig 2008-11-19 16:47:04.000000000 +0530 @@ -3,6 +3,40 @@ 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 @@ -36,6 +70,8 @@ source "sound/oss/dmasound/Kconfig" if !M68K + + menu "Advanced Linux Sound Architecture" depends on SOUND!=n diff -Nauprw linux-2.6.20/sound/Makefile ../new/linux-2.6.20/sound/Makefile --- linux-2.6.20/sound/Makefile 2007-02-05 00:14:54.000000000 +0530 +++ ../new/linux-2.6.20/sound/Makefile 2007-11-21 11:51:42.000000000 +0530 @@ -1,6 +1,7 @@ # 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/ @@ -15,4 +16,12 @@ 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 diff -Nauprw linux-2.6.20/sound/nomadik_stw5094.c ../new/linux-2.6.20/sound/nomadik_stw5094.c --- linux-2.6.20/sound/nomadik_stw5094.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/sound/nomadik_stw5094.c 2008-07-04 23:45:32.000000000 +0530 @@ -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); diff -Nauprw linux-2.6.20/sound/nomadik_stw5095.c ../new/linux-2.6.20/sound/nomadik_stw5095.c --- linux-2.6.20/sound/nomadik_stw5095.c 1970-01-01 05:30:00.000000000 +0530 +++ ../new/linux-2.6.20/sound/nomadik_stw5095.c 2008-11-24 14:06:29.000000000 +0530 @@ -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<