HSI

=What is HSI ?= The MIPI High Speed Synchronous Serial Interface (HSI) is a high speed communication interface that is used for connecting OMAP to a cellular modem engine. It is specified by the MIPI alliance (www.mipi.org). An introduction to the MIPI HSI working group can be found here: http://www.mipi.org/working-groups/high-speed-synchronous-interface

The HSI interface supports full duplex communication over multiple channels and is capable of reaching speeds up to 200 Mbit/s.

HSI link is the recommended IPC for OMAP4 modem connectivity. It offers a high speed multi-channel interface to connect 3G and 4G (up to LTE Category 3) modems. The OMAP HSI driver supports both OMAP MIPI HSI (as defined in MIPI documentation mipi_HSI-PL_specification_v01-01-00a.pdf) and OMAP SSI devices through different device files, and a generic SW driver.



Please refer to the MIPI specifications for more details on this device: http://www.mipi.org/specifications/high-speed-synchronous-serial-interface-hsi

=A little background on HSI drivers=

There are 2 HSI drivers : One owned by Modem Integration team (Google Hub), one owned by LDC(TI Linux Development Center).

HSI Driver 1: Modem Integration HSI driver
 * this is HSI driver currently present in p-android-omap-2.6.35, p-android-omap-3.0 and p-android-omap-3.1 (kernel/drivers/omap_hsi) and currently in production since K2.6.35
 * This driver is the one used by all customers using STE, IMC or Renesas modems (Samsung, LGE, Moto, Huawei, PMC etc…) on OMAP4.
 * This driver will also be used on OMAP5 by STE POR modem
 * Supports HSI(OMAP4+) and SSI(OMAP3)
 * Additionally this driver also support various Link Layers on top of it (every modem partner or customer has its own Link Layer).
 * This driver is pretty mature and changes are :
 * bug fixes are mainly to fix the issues seen at customers to comply with changes in modem side or Link Layer.
 * Kernel framework changes (PM, mux, hwmod, etc…)
 * All patches are pushed to Gerrit (http://review.omapzoom.org)
 * Owner is Elaidi, Djamil (Modem Integration team, Google Hub)

Driver 2: LDC HSI driver, based on Nokia RFC
 * This is a whole new driver, with 0% lines in common with previous HSI driver.
 * Purpose of this LDC new driver is to upstream
 * Nokia started this upstream driver in 2010 for SSI, and it is still not upstream, since a lot of people in open source community are also contributing.
 * LDC started in 2Q2011 to develop a OMAP HSI version of this driver
 * Timeframe for driver upstream is unknown.
 * From the beginning Modem Integration team and LDC agreed that this driver will not be ready in time for OMAP5
 * Fixes posted in Gerrit for Modem Integration HSI driver shall be watched and absorbed by LDC team owning the LDC HSI driver.
 * Since the 2 drivers are completely differents, patches for Modem Integration HSI driver cannot apply directly to LDC HSI driver
 * Owner is Datta, Shubhrajyoti (LDC)

So as there are 2 HSI drivers, one shall not confuse the 2 of them. Patches pushed in Gerrit and merged to TI android branches only concern Modem Integration HSI driver (Driver 1).

The current page refers only to android HSI driver (Driver 1)

=Where is HSI driver ?=

In TI Android mainlines
HSI driver is part of TI official releases for Android OMAP4 and OMAP5. TI branches containing HSI driver are at http://review.omapzoom.org :
 * On Kernel 2.6.35, Source code is available in branch p-android-omap-2.6.35 under directory [kernel/omap.git]/drivers/staging/omap_hsi/


 * On Kernel 3.0, Source code is available in branch p-android-omap-3.0 under directory [kernel/omap.git]/drivers/omap_hsi/


 * On Kernel 3.1, Source code is available in branch p-android-omap-3.1 under directory [kernel/omap.git]/drivers/omap_hsi/


 * On Kernel 3.4, Source code is available in branch p-android-omap-3.4 under directory [kernel/omap.git]/drivers/omap_hsi/

Ex.for K3.1: http://git.omapzoom.org/?p=kernel/omap.git;a=tree;f=drivers/omap_hsi;h=ae899ab1abae144eeb6d61da64b5b68c58b19766;hb=refs/heads/p-android-omap-3.1

In HSI feature tree
HSI driver feature tree for K3.0 and higher is https://gitorious.tif.ti.com/modem-integration/mipi-hsi

=Linux OMAP HSI Physical Driver (omap_hsi)=

The OMAP HSI driver kernel documentation is available here:
 * Kernel 2.6.35:


 * Kernel 3.1:

Services provided by the Linux HSI driver

 * The Linux HSI driver implements the PHYsical layer.
 * Management of:
 * WAKE, DATA, FLAG and READY signals following SSI/HSI specifications
 * RX/TX state machines
 * HSI FIFOs
 * HSI DMA
 * Transmission mode (stream/frame)
 * Errors
 * HSI Power Management
 * platform wake-up related to modem events (through HSI wake line)
 * Generic abstraction layer: provides an HSI virtual BUS and HSI virtual devices for each channel, mapped on HSI logical channels
 * Kernel space interface and optional user space interface


 * Services NOT provided (belong to higher SW layers):
 * Management of platform reset
 * Data Link Protocol / assignment of channels to dedicated roles (control / data)
 * Synchronize / inform peer of transactions on the link and transmission parameters (speed, mode, flow, number of channels, …)
 * Synchronize PM states between modem and ABE (Frequency and voltage changes)

HSI Linux driver kernel interfaces

 * Register an HSI driver, to use a pre-defined set of HSI ports / channels
 * open / read / write / configuration operations on HSI channels
 * Callbacks for read / write complete and asynchronous events (errors, break frames)

Basic rules to reach maximum throughput

 * During RX/TX phase, at least one DMA shall be programmed in OMAP HSI HW.
 * Side effet : while a HSI DMA is set, HSI STANDBY and IDLE protocols are not entered, preventing L3INIT_PD to enter Low Power Mode.
 * Next DMA (for HSI channel 1) shall have been already programmed when current DMA (for HSI channel 2) is over.
 * Failure or delay in programming a DMA has a direct negative impact on throughput.
 * As it not possible to queue multiple DMA requests for a single HSI channel (HW limitation), several HSI channels shall be used.
 * When CP sends L2 header (containing size of next packet) :
 * AP shall not sent an ACK to acknowledge previous L2 header.
 * Instead AP shall immediatly post a HSI read of the size given by L2 header.
 * CP shall also send the data packet immediatly after the header. The AC_READY protocol will take care of suspending the CP->AP transfer if AP-HSI is not ready.
 * These rules apply for DL (DMA read, CP->AP) or UL (DMA write, AP->CP)

Additional rules to reach maximum throughput

 * Usage of hsi_perf measurement module shows that :
 * Best throughput is obtained in Stream pipelined mode, HSI FClk = 192MHz, DMA burst mode.
 * The bigger the number of frames in a DMA burst is, the greater the throughput is.
 * Throughput starts to be maximal from DMA transfer of 10000 frames
 * At least 2 HSI channels shall be used concurrently, with always a read and a write pending on these each channel. This guaranties maximum efficiency as HSI HW will not underrun

Full details can be found here:

Responsibilities Split
HSI power management strategy requires a shared alignment between the modem partner & TI.
 * HSI Data Link Protocol driver responsibility
 * Wake lines Management requires upper-layer SW control, dependent on the modem protocol:
 * ACWAKE is explicitly asserted and reset under HSI DLP driver control
 * CAWAKE change events are reported to HSI DLP driver
 * System suspend
 * System must be kept awake as long as a RX/TX is ongoing (usage of wakelock by upper layers )


 * OMAP HSI physical driver responsibility
 * Clock management (functional and interface clocks)
 * In kernel 2.6.32, static clock management was made through direct calls to Clock Framework
 * Since kernel 2.6.35, HSI driver uses Runtime PM + omap_device + HWMOD
 * Wake-up from OFF mode
 * Requires OMAP IO daisy chain HW+SW mechanism
 * Context Save/Restore SW mechanism
 * The HSI HW context is saved automatically by the HSI SW driver when disabling HSI clocks and restored upon clock enable.
 * OPP change
 * HSI driver provides simplified APIs to change HSI functional clock through usage of DVFS framework
 * More details on OPP Layer here
 * System suspend (platform entering DEVICE-OFF)
 * System must be kept awake as long as a RX/TX is ongoing. HSI driver will reject any platform suspend request made by kernel PM framework until HSI activity is ongoing.

OMAP4 MIPI HSI Power management rules

 * WAKE lines protocol rules:
 * Wake-up
 * Both OMAP and Modem can initiate a wakeup by raising their WAKE line
 * Low power mode
 * OMAP HSI can enter into LPM only once ACWAKE and CAWAKE lines are low.
 * Once ACWAKE has been set low, OMAP waits for the CAWAKE to go also low, then put the OMAP HSI into LPM.
 * Any wake-up or sleep request must not be aborted until counterpart has acknowledged the initial request
 * DLP/Link Layer shall :
 * Raise the ACWAKE line before communicating with Modem
 * Lower the ACWAKE line every time for every idle period

Note : « wake-up » or « sleep » are related to HSI HW state, not OMAP or Modem state.

HSI Dynamic OPP change
Full details can be found here:

Background

 * TI OMAP HSI IP :
 * HSI RX and TX bit rate :
 * depends on HSI Functional clock
 * cannot be higher than Fclk
 * HSI Functional clock can be clocked by 96MHz or 192MHz
 * Max Speed is achieved using 192MHz Fclk, stream pipelined mode
 * HSI is part of L3INIT Power Domain, L3INIT_PD is in CORE voltage domain
 * HSI available OPPs are :
 * OPP50 (96MHz, 0.962V)
 * OPP100 (192MHz, 1.127V)
 * HSI can run at :
 * 96MHz with both voltages.
 * 192MHz only if powered by 1.127V, otherwise it will crash.
 * It is necessary to switch L3INIT_PD to 1.127V to allow HSI@OPP100 & achieve max throughput
 * But obviously there is a drawback of running HSI@OPP100 :
 * HSI@OPP100 has a negative impact on power management, so it is necessary to go back to OPP50 as soon as high throughput is no more required.

Implementation

 * Added IOCTL only on kernel 3.0 and higher, branches p-android-omap-3.0, 3.4
 * To change HSI FClk to 96MHz or 192MHz
 * hsi_ioctl(HSI_IOCTL_SET_HI_SPEED, 0) : switch to OPP50 (96MHz)
 * hsi_ioctl(HSI_IOCTL_SET_HI_SPEED, 1) : switch to OPP100 (192MHz)
 * OMAP PM API for device scaling use mutexes, so hsi_ioctl(HSI_IOCTL_SET_HI_SPEED, x) might sleep.
 * RX/TX divisors and RX error counters are not automatially changed with this ioctl.
 * To get current HSI FClk
 * hsi_ioctl(HSI_IOCTL_GET_SPEED, &clk) : returns 96000000 or 192000000

Interface with upper layers

 * Decision of when to increase/decrease modem speed is up to Link Layer.
 * AP-LL and CP-LL must synchronize to know when HSI link speed is changing and when change is over.
 * If CP-HSI speed is increased to 192MHz (or more than 96Mhz), AP-HSI must switch to OPP100.
 * If CP-HSI speed is decreased to less than 96Mhz, AP-HSI can switch to OPP50 to allow power saving.
 * Constraints :
 * After OPP is changed, Link Layer shall change RX/TX divisors and RX error counters (divided or multiplied by 2) using hsi_ioctl(HSI_IOCTL_SET_RX) and hsi_ioctl(HSI_IOCTL_SET_TX)
 * Link Layer shall ensure :
 * No read or write are ongoing when OPP change is started
 * No read or write are started while OPP change is ongoing
 * No data is received while OPP change is ongoing
 * HSI driver will :
 * Reject OPP change (-EBUSY) if any Read or Write is pending
 * Reject read or write operation (-EAGAIN) if OPP change operation is ongoing
 * In case AP HSI receives data without any explicit HSI read, up to 8 frames can be received per channel until AC_READY is lowered. In this case if OPP change operation occurs during data reception, data integrity is not guarantied and HSI driver may raise errors.

Latencies

 * In K3.0 OMAP PM API for device scaling use mutexes (one for all power domains), so if a device scale is already in progress, latency will increase.


 * With DVFS framework from K3.0, measurements using Ftrace show omap_device_scale takes to complete in average 300us.
 * Condition : low CPU load, not sure about worst case latency
 * No SW measurable difference between OPP50->OPP100 & OPP100->OPP50 transitions.


 * Architecture measurements (DVFS framework from K35)
 * OPP50->OPP100 : 579.5us (518.5us@OPP50 + 61us@OPP100)
 * OPP100->OPP50 : 610us (122us@OPP100 + 488us@OPP50)


 * Recommendation is (between SW OPP request and effective OPP change) : 1ms
 * This latency doesn’t include AP-CP OPP change handshake

Runtime suspend and resume
Since kernel 2.6.35, HSI driver fully supports runtime PM. HSI driver enables and disables HSI Functional clock (FClk) and HSI Interface Clock(IClk) on a need basis. This is done using runtime PM APIs pm_runtime_get_sync and pm_runtime_put_sync_suspend.

Every time an HSI access is needed, HSI driver enables the clocks. Once HSI HW access is over, HSI driver disables the clocks if the HSI controller is not busy.

HSI controller is declared busy if one of the following conditions is true: For all port of the HSI controller:
 * ACWAKE is high
 * CAWAKE is high
 * data transfer (Write) is ongoing for a given HSI channel
 * CAWAKE is not used (receiver in 3-wires mode)
 * Currently in HSI interrupt tasklet
 * Currently in HSI DMA interrupt tasklet
 * Currently in HSI CAWAKE tasklet (for SSI)
 * Clocks have been explicitly set in forced ON mode using HSI ioctl

Platform suspend and resume
When entering system wide suspend, the following hooks are called :
 * ->prepare hook (hsi_pm_prepare) then
 * ->suspend hook (hsi_pm_suspend) then
 * ->suspend_noirq hook (hsi_pm_suspend_noirq)

These hooks correspond to the differents phases of entering system suspend (cf. \Documentation\power\devices.txt) Each of these hooks gives a chance to HSI driver to prevent the system suspend. Any of these hooks will return -EBUSY if HSI is busy (cf. conditions here)

Pros of this implementation: Cons of this implementation:
 * Cleaner (suspend mode is really hit when all devices allow it)
 * L3INIT_PD devices will only switch to IO daisy chain if really needed
 * For L3INIT_PD devices, Context save and restore is made only when needed
 * avoids unneeded suspend phases.
 * Console trace is spammed with lot of suspend retries every 300 or 400ms until CAWAKE is low
 * Since Suspend is not entered at all when CAWAKE is high, the CPU will not be OFF during all the retry duration but may only reach RET_OSRW as it is the deepest state possible for CPU using CPUidle
 * there are a lot of “pseudo suspend” possibilities which are missed and replaced by CPUidle phases. So CPU doesn’t enter OFF. L3INIT_PD and CORE_PD are ON. All other power domain are in their deepest power state.

Background

 * HSI wakeup latencies
 * When the HSI clocks are disable, the L3INIT Power Domains is allowed to go into sleep state that can be INACTIVE, Open Switch Retention, Closed Switch Retention and if the system can sleep too in OFF state. A wakeup from a lower state add a wakeup delay.
 * To control these wakeup delays we added an IOCTL adding a constraint on the L3INIT PD.
 * MPU wakeup latencies
 * Between HSI Interrupts (HSI IRQ, DMA Requests), the MPU can enter C states. It will add a delay to handle the HSI event.
 * To control these delays we added an IOCTL adding a constraint on the MPU/CORE PD.

Implementation

 * Added IOCTL only on kernel 3.4, branch p-android-omap-3.4
 * To change HSI device wakeup latency
 * Set a constraint on HSI/L3INIT_PD to change HSI wakeup latency
 * hsi_ioctl(HSI_IOCTL_SET_HSI_LATENCY, -1) : Release the constraint
 * hsi_ioctl(HSI_IOCTL_SET_HSI_LATENCY, 1) : Force L3INIT PD in ON to keep the lowest HSI wakeup latency possible
 * You can set the parameter in Microseconds meaning the minimum wakeup latency acceptable on the L3INIT PD which will be the minimum delay on the HSI wakeup. The maximum targeted sleep state of the L3INIT PD will be configured respectively.
 * To get current HSI device wakeup latency
 * hsi_ioctl(HSI_IOCTL_GET_HSI_LATENCY, &lat) : returns value in Microseconds
 * To change MPU wakeup latency
 * Set a constraint on MPU/CORE to change MPU wakeup latency
 * This configure which C-state will be used in CPUidle
 * hsi_ioctl(HSI_IOCTL_SET_MPU_LATENCY, us) : Latency to use in Microseconds
 * To get current MPU wakeup latency
 * hsi_ioctl(HSI_IOCTL_GET_MPU_LATENCY, &lat) : returns value in Microseconds

Port 2 support
HSI supports Port 2 usage from kernel 3.1 and higher.
 * OMAP4 preferred HSI port is port 1
 * OMAP5 preferred HSI port is port 2

=HSI debug=

HSI dynamic debug
HSI driver uses dynamic debug feature of kernel. Here is what to do to enable it :

Build kernel with : CONFIG_DYNAMIC_DEBUG=y

After boot :
 * mount -t debugfs debugfs 

Usually is /d or /debugfs


 * echo -n 'module omap_hsi +p' > / /dynamic_debug/control

but this is a lot of trace, so you can remove the one that you consider as spam for this issue by :


 * cat / /dynamic_debug/control | grep hsi
 * echo -n 'file hsi_driver_bus.c line 201 -p' > / /dynamic_debug/control
 * etc...


 * To add a single trace
 * echo -n 'file hsi_driver_bus.c line 201 +p' > / /dynamic_debug/control


 * To remove a single trace
 * echo -n 'file hsi_driver_bus.c line 201 -p' > / /dynamic_debug/control


 * To add all traces for complete hsi module
 * echo -n 'module omap_hsi +p' > / /dynamic_debug/control
 * echo -n 'module hsi_char +p' > / /dynamic_debug/control


 * To remove all traces for complete hsi module
 * echo -n 'module omap_hsi -p' > / /dynamic_debug/control
 * echo -n 'module hsi_char -p' > / /dynamic_debug/control

As a first step, I recommend setting the following traces only :
 * Minimum traces


 * Wakeup
 * ''echo -n 'func omap_hsi_wakeup +p' > / /dynamic_debug/control
 * echo -n 'func hsi_do_cawake_process +p' > / /dynamic_debug/control
 * echo -n 'func omap_hsi_wakeup_enable +p' > / /dynamic_debug/control
 * echo -n 'func omap_hsi_wakeup_disable +p' > / /dynamic_debug/control''


 * Clocks
 * ''echo -n 'func hsi_clocks_enable_channel +p' > / /dynamic_debug/control
 * echo -n 'func hsi_clocks_disable_channel +p' > / /dynamic_debug/control
 * echo -n 'func hsi_runtime_resume +p' > / /dynamic_debug/control
 * echo -n 'func hsi_runtime_suspend +p' > / /dynamic_debug/control
 * echo -n 'func hsi_runtime_idle +p' > / /dynamic_debug/control
 * echo -n 'func hsi_pm_prepare +p' > / /dynamic_debug/control
 * echo -n 'func hsi_pm_suspend +p' > / /dynamic_debug/control
 * echo -n 'func hsi_pm_suspend_noirq +p' > / /dynamic_debug/control
 * echo -n 'func hsi_pm_resume +p' > / /dynamic_debug/control''


 * R/W
 * ''echo -n 'func hsi_write +p' > / /dynamic_debug/control
 * echo -n 'func hsi_read +p' > / /dynamic_debug/control
 * echo -n 'func do_hsi_gdd_lch +p' > / /dynamic_debug/control
 * echo -n 'func hsi_do_channel_rx +p' > / /dynamic_debug/control
 * echo -n 'func hsi_do_channel_tx +p' > / /dynamic_debug/control''

You should obtain something like: example: <7>omap_hsi omap_hsi.0: Int Tasklet : clock_enabled=1 <7>omap_hsi omap_hsi.0: CLK: hsi_clocks_enable: do_hsi_tasklet <7>omap_hsi omap_hsi.0: Clocks already enabled, skipping... <7>omap_hsi omap_hsi.0: Channels [0,7] : Events 0x00000100 <7>omap_hsi omap_hsi.0: Data Available interrupt for channel 0. <7>omap_hsi omap_hsi.0: Channels [8,15] : no event, exit. <7>omap_hsi omap_hsi.0: CLK: hsi_clocks_disable: do_hsi_tasklet <7>omap_hsi omap_hsi.0: Port 1: WAKE status: acwake_status 1,cur_cawake 1 <7>omap_hsi omap_hsi.0: Port 1 busy <7>omap_hsi omap_hsi.0: Cannot disable clocks, HSI port busy <7>omap_hsi omap_hsi.0: Int Tasklet : clock_enabled=1 <7>omap_hsi omap_hsi.0: CLK: hsi_clocks_enable: do_hsi_tasklet
 * Trace output example

HSI core debug
HSI Driver has a debugfs directory, where you can access all the HSI registers: / /hsi/omap_hsi0/

E.g. cat / /hsi/omap_hsi0/port1/regs cat / /hsi/omap_hsi0/port1/counters cat / /hsi/omap_hsi0/regs cat / /hsi/omap_hsi0/gdd/regs

HSI Power Management debug
TBC

=HSI Standalone Testing=

Test code location
Where to get the hsi_test and hsi_perf code ? git clone git@gitorious.tif.ti.com:modem-integration/hsi-test.git

Public url will come soon.

Test setup
Running these tests imply having setup the following: 1) a test platform (board) hosting a compatible HSI device 2) Either: plug 2 boards together through their HSI port 1 (1st HSI port): HSI Tx wires of board 1 connected to HSI Rx wires of board 2 HSI Rx wires of board 1 connected to HSI Tx wires of board 2 or loopback the HSI signals of HSI port 1 of a single test board: ACwake <-> CAWake ACReady <-> CAReady ACData <-> CAData ACFlag <-> CAFlag or connect the OMAP HSI to a modem and perform loopback in the modem

hsi_test
This test application is used to debug and test the HSI device drivers by interfacing at HSI char driver level. It is a user space application that has no dependency on the kernel, except for the IOCTL constants definitions appearing in hsi_char.h (although these constants could be re-defined locally).

The test application can use up to 4 HSI channels simultaneously, but for most of tests, only channel 0 is used. Note that when only channel 0 is required, the other channels are not opened. The HSI port 1 (1st HSI port) is used. Port 2 is not used with this setting.

hsi_perf
The HSI throughput measurement module is an out-of-tree kernel module, used to measure the HSI driver throughput in various configurations. This module sends and receives data using loopback mode. It doesn't check the validity of the received data vs what was sent previously. The test starts immediatly when hsi_perf module is loaded.

hsi_perf architecture information
This section is dedicated to help anyone who would like to look into the hsi_perf module code.

When loaded, hsi_perf module will :
 * register itself as a user of HSI driver
 * open the required number of channels and configure the TX and RX parameters
 * create as many kernel threads for write as there are channels opened
 * create as many kernel threads for read as there are channels opened
 * create one kernel thread to display measurement results

Synchronisation between kernel threads : hsi_perf uses mutexes and R/W semaphores to synchronize between kernel threads and make sure every thread starts when needed.

For each channel, 2 mutexes are created :
 * one to start a new write once previous write is over
 * one to start a new read once previous read is over

Also, there is a Read/Write semaphore used to allow the display measurement kthread to be run once all other read and write are over : until all reader smeaphores are released
 * Every read or write kernel thread created will acquire a reader semaphore
 * Every complete read or write will release a reader semaphore
 * The display measurement kthread will try to acquire a writer semaphore, which will cause the kthread to sleep

HSI Test points on OMAP44xx Processor board
=HSI warning & error message interpretation=

Missed previous CAWAKE falling edge

 * This trace means a CAWAKE low glitch has been detected by HSI driver e.g.CAWAKE has toggled to low (High->Low->High transition) for a very short time, insufficient for the HSI tasklet to process correctly the CAWAKE low event.
 * This trace is printed if the following sequence occurs :
 * CAWAKE is high and HSI is active, eg. :
 * HSI clocks are enabled
 * HSI wakeup event doesn't use IO Daisy chain mechanism
 * HSI internal variable cawake_status is set to 1
 * CAWAKE goes low for a vey short period (less than 600us)
 * HSI tasklet is scheduled to process the CAWAKE low event
 * Before HSI tasklet has been executed to process CAWAKE falling edge and cawake_status can be set to 0, CAWAKE goes high again
 * So HSI tasklet is fooled by the new value of CAWAKE (high) and thinks it is a rising edge. But when HSI compares to previous cawake_status value, it founds out that CAWAKE was already high. So HSI driver knows there has been a missed CAWAKE falling edge and prints the warning message “Missed previous CAWAKE falling edge”

HSI driver is able to recover from such a warning.

Missed previous CAWAKE rising edge

 * This trace is printed if the following sequence occurs :
 * CAWAKE is low and HSI is inactive, eg. :
 * HSI clocks have been disabled
 * HSI wakeup event now goes through IO Daisy chain mechanism
 * HSI internal variable cawake_status is set to 0
 * Modem wants to transmit to OMAP, so CAWAKE goes high, so OMAP is awaken,
 * PRCM interrupt is raised and HSI tasklet is scheduled
 * Before HSI tasklet has been completed to process CAWAKE rising edge and cawake_status can be set to 1, CAWAKE goes low again
 * So HSI tasklet is fooled by the new value of CAWAKE (low) and thinks it is a falling edge. But when HSI compares to previous cawake_status value, it founds out that CAWAKE was already low. So HSI driver knows there has been a missed CAWAKE rising edge and prints the warning message “Missed previous CAWAKE rising edge”


 * I have measured that if CAWAKE goes low less than 1.2ms after CAWAKE went high, then this error is triggered. So time between point 1 and 4 shall be more than 1.2ms. of course this depends on CPU load, etc…

HSI driver is able to recover from such a warning.

New CAWAKE interrupt detected during interrupt processing

 * This trace occurs when HSI tasklet is executing and processing a CAWAKE event (high or low) and another CAWAKE event occurs while previous processign is not yet over.

HSI driver is able to recover from such a warning.