Introduce new functions gsi_suspend() and gsi_resume(), which will
disable the GSI interrupt handler after all endpoints are suspended
and re-enable it before endpoints are resumed. This will ensure no
GSI interrupt handler will fire when the hardware is suspended.
Here's a little further explanation. There are seven GSI interrupt
types, and most are disabled except when needed.
- These two are not used (never enabled):
GSI_INTER_EE_CH_CTRL
GSI_INTER_EE_EV_CTRL
- These two are only used to implement channel and event ring
commands, and are only enabled while a command is underway:
GSI_CH_CTRL
GSI_EV_CTRL
- The IEOB interrupt signals I/O completion. It will not fire
when a channel is stopped (or "suspended").
GSI_IEOB
- This interrupt is used to allocate or halt modem channels,
and is only enabled while such a command is underway.
GSI_GLOB_EE
However it also is used to signal certain errors, and this could
occur at any time.
- The general interrupt signals general errors, and could occur at
any time.
GSI_GENERAL
The purpose for this change is to ensure no global or general
interrupts fire due to errors while the hardware is suspended.
We enable the clock on resume, and at that time we can "handle"
(at least report) these error conditions.
Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
The GSI layer has the IPA version now, so there's no need for
version-specific flags to be passed from IPA. One instance of
this is in gsi_channel_suspend() and gsi_channel_resume(), which
indicate whether or not the endpoint suspend is implemented by
GSI stopping the channel. We can make that determination based
on gsi->version, eliminating the need for a Boolean flag in those
functions.
Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Prior to IPA v3.5.1, there is no HW_PARAM_2 GSI register, which we
use to determine the number of channels and endpoints per execution
environment. In that case, we will just assume the number supported
is the maximum supported by the driver.
Introduce gsi_ring_setup() to encapsulate the code that determines
the number of channels and endpoints.
Update GSI_EVT_RING_COUNT_MAX so it is big enough to handle any
available channel for all supported hardware (IPA v4.9 can have 23
channels and 24 event rings).
Signed-off-by: Alex Elder <elder@linaro.org>
Acked-by: AngeloGioacchino Del Regno
Signed-off-by: David S. Miller <davem@davemloft.net>
Increase the maximum number of channels and event rings supported by
the driver, to allow the maximum available on the SDX55.
Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
This patch actually fixes a bug, though it doesn't affect the two
platforms supported currently. The fix implements GSI memory
pointers a bit differently.
For IPA version 4.5 and above, the address space for almost all GSI
registers is adjusted downward by a fixed amount. This is currently
handled by adjusting the I/O virtual address pointer after it has
been mapped. The bug is that the pointer is not "de-adjusted" as it
should be when it's unmapped.
This patch fixes that error, but it does so by maintaining one "raw"
pointer for the mapped memory range. This is assigned when the
memory is mapped and used to unmap the memory. This pointer is also
used to access the two registers that do *not* sit in the "adjusted"
memory space.
Rather than adjusting *that* pointer, we maintain a separate pointer
that's an adjusted copy of the "raw" pointer, and that is used for
most GSI register accesses.
Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
An event ring's state only needs to be known when it is allocated,
reset, or deallocated. We check an event ring's state both before
and after performing an event ring control command that changes
its state. These are only issued at startup and shutdown, so there
is very little value in caching the state.
Stop recording a copy of the channel's last known state, and instead
fetch the true state from hardware whenever it's needed. In such
cases, *do* record the state in a local variable, in case an error
message reports it (so the value reported is the value seen).
Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
When stopping an AP RX channel, there can be a transient period
while the channel enters STOP_IN_PROC state before reaching the
final STOPPED state. In that case we make another attempt to stop
the channel.
Similarly, when stopping a modem channel (using a GSI generic
command issued from the AP), it's possible that multiple attempts
will be required before the channel reaches STOPPED state.
Add a field to the GSI structure to record an errno representing the
result code provided when a generic command completes. If the
result learned in gsi_isr_gp_int1() is RETRY, record -EAGAIN in the
result code, otherwise record 0 for success, or -EIO for any other
result.
If we time out nf gsi_generic_command() waiting for the command to
complete, return -ETIMEDOUT (as before). Otherwise return the
result stashed by gsi_isr_gp_int1().
Add a loop in gsi_modem_channel_halt() to reissue the HALT command
if the result code indicates -EAGAIN. Limit this to 10 retries
(after the initial attempt).
Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Consistently define numeric values for enumerated type members using
hexidecimal (rather than decimal) format values. Align the values
assigned in the same column in each file.
Only assign values where they really matter, for example don't
assign IPA_ENDPOINT_AP_MODEM_TX the value 0.
Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Keep track of the set of GSI interrupt types that are currently
enabled by recording the mask value to write (or last written) to
the TYPE_IRQ_MSK register.
Create a new helper function gsi_irq_type_update() to handle
actually writing the register.
Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Rename the "event_enable_bitmap" field of the GSI structure to be
"ieob_enabled_bitmap". An upcoming patch will cache the last value
stored for another interrupt mask and this is a more direct naming
convention to follow.
Add a few comments to explain the bitmap fields in the GSI structure.
Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
We enable a channel doorbell engine only for IPA v3.5.1, and that is
now handled directly by gsi_channel_program().
When initially setting up a channel, we want that doorbell engine
enabled, and we can request that independent of the IPA version.
Doing that makes the "legacy" argument to gsi_channel_setup_one()
unnecessary. And with that gone we can get rid of the "legacy"
argument to gsi_channel_setup(), and gsi_setup() as well.
Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Use the IPA version in gsi_channel_program() to determine whether
we should enable the GSI doorbell engine when requested. This way,
callers only say whether or not it should be enabled if needed,
regardless of hardware version.
Rename the "legacy" argument to gsi_channel_reset(), and have
it indicate whether the doorbell engine should be enabled when
reprogramming following the reset.
Change all callers of gsi_channel_reset() to indicate whether to
enable the doorbell engine after reset, independent of hardware
version.
Rework a little logic in ipa_endpoint_reset() to get rid of the
"legacy" variable previously passed to gsi_channel_reset().
Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Record the IPA version passed to gsi_init() in the GSI structure.
This allows that value to be used directly where needed, rather than
passing and storing certain flag arguments through the code.
In particular, for all but one supported version of IPA, the command
channel is programmed to only use an "escape buffer". By storing
the IPA version, we can do a simple version check in one location,
and avoid storing a flag field in every channel (and passing a flag
along while initializing channels to set that field properly).
Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Although GSI is integral to IPA, it is a separate hardware component
and the IPA code supporting it has been structured to avoid explicit
dependence on IPA details. An example of this is that gsi_init() is
passed a number of Boolean flags to indicate special behaviors,
whose values are dependent on the IPA hardware version. Looking
ahead, newer hardware versions would require even more such special
behaviors.
For any given version of IPA hardware (like 3.5.1 or 4.2), the GSI
hardware version is fixed (in this case, 1.3 and 2.2, respectively).
So the IPA version *implies* the GSI version, and the IPA version
can be used as effectively the equivalent of the GSI hardware version.
Rather than proliferating new special behavior flags, just provide
the IPA version to the GSI layer when it is initialized. The GSI
code can then use that directly to determine whether special
behaviors are required. The IPA version enumerated type is already
isolated to its own header file, so the exposure of this IPA detail
is very limited.
For now, just change gsi_init() to pass the version rather than the
Boolean flags, and set the flag values internal to that function.
Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
We now trigger a system resume when we receive an IPA SUSPEND
interrupt. We should *not* wake up on GSI interrupts.
Signed-off-by: Alex Elder <elder@linaro.org>
Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit affects comments (and in one case, whitespace) only.
Throughout the IPA code, return statements are documented using
"@Return:", whereas they should use "Return:" instead. Fix these
mistakes.
In function definitions, some parameters are missing their comment
to describe them. And in structure definitions, some fields are
missing their comment to describe them. Add these missing
descriptions.
Some arguments changed name and type along the way, but their
descriptions were not updated (an endpoint pointer is now used in
many places that previously used an endpoint ID). Fix these
incorrect parameter descriptions.
In the description for the ipa_clock structure, one field had a
semicolon instead of a colon in its description. Fix this.
Add a missing function description for ipa_gsi_endpoint_data_empty().
All of these issues were identified when building with "W=1".
Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
In several places, a Boolean flag is used in the GSI code to
indicate whether the "doorbell engine" should be enabled or not
when a channel is configured. This is basically done to abstract
this property from the IPA version; the GSI code doesn't otherwise
"know" what the IPA hardware version is. The doorbell engine is
enabled only for IPA v3.5.1, not for IPA v4.0 and later.
The next patch makes another change that affects behavior during
channel reset (which also involves programming the channel). It
also distinguishes IPA v3.5.1 hardware from newer hardware.
Rather than creating another flag whose value matches the "db_enable"
value, just rename "db_enable" to be "legacy" so it can be used to
signal more than just the special doorbell handling.
Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
It is possible for a GSI channel's state to be changed as a result
of an action by a different execution environment. Specifically,
the modem is able to issue a GSI generic command that causes a state
change on a GSI channel associated with the AP.
A channel's state only needs to be known when a channel is allocated
or deallocaed, started or stopped, or reset. So there is little
value in caching the state anyway.
Stop recording a copy of the channel's last known state, and instead
fetch the true state from hardware whenever it's needed. In such
cases, *do* record the state in a local variable, in case an error
message reports it (so the value reported is the value seen).
Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
The Generic Software Interface is a layer of the IPA driver that
abstracts the underlying hardware. The next patch includes the
main code for GSI (including some additional documentation). This
patch just includes three GSI header files.
- "gsi.h" is the top-level GSI header file. This structure is
is embedded within the IPA structure. The main abstraction
implemented by the GSI code is the channel, and this header
exposes several operations that can be performed on a GSI channel.
- "gsi_private.h" exposes some definitions that are intended to be
private, used only by the main GSI code and the GSI transaction
code (defined in an upcoming patch).
- Like "ipa_reg.h", "gsi_reg.h" defines the offsets of the 32-bit
registers used by the GSI layer, along with masks that define the
position and width of fields less than 32 bits located within
these registers.
Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: David S. Miller <davem@davemloft.net>