The IPA BCM resource ("IP0") on sc7180 was moved to the clk-rpmh driver
in commit bcd63d222b ("clk: qcom: rpmh: Add IPA clock for SC7180") and
modeled as a clk, but this interconnect driver still had it modeled as
an interconnect. This was mostly OK because nobody used the interconnect
definition, until the interconnect framework started dropping bandwidth
requests on interconnects that aren't used via the sync_state callback
in commit 7d3b0b0d81 ("interconnect: qcom: Use icc_sync_state"). Once
that patch was applied the IP0 resource was going to be controlled from
two places, the clk framework and the interconnect framework.
Even then, things were probably going to be OK, because commit
b95b668eaa ("interconnect: qcom: icc-rpmh: Add BCMs to commit list in
pre_aggregate") was needed to actually drop bandwidth requests on unused
interconnects, of which the IPA was one of the interconnect that wasn't
getting dropped to zero. Combining the three commits together leads to
bad behavior where the interconnect framework is disabling the IP0
resource because it has no users while the clk framework thinks the IP0
resource is on because the only user, the IPA driver, has turned it on
via clk_prepare_enable(). Depending on when sync_state is called, we can
get into a situation like below:
IPA driver probes
IPA driver gets notified modem started
runtime PM get()
IPA clk enabled -> IP0 resource is ON
sync_state runs
interconnect zeroes out the IP0 resource -> IP0 resource is off
IPA driver tries to access a register and blows up
The crash is an unclocked access that manifest as an SError.
SError Interrupt on CPU0, code 0xbe000011 -- SError
CPU: 0 PID: 3595 Comm: mmdata_mgr Not tainted 5.17.1+ #166
Hardware name: Google Lazor (rev1 - 2) with LTE (DT)
pstate: 60400009 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
pc : mutex_lock+0x4c/0x80
lr : mutex_lock+0x30/0x80
sp : ffffffc00da9b9c0
x29: ffffffc00da9b9c0 x28: 0000000000000000 x27: 0000000000000000
x26: ffffffc00da9bc90 x25: ffffff80c2024010 x24: ffffff80c2024000
x23: ffffff8083100000 x22: ffffff80831000d0 x21: ffffff80831000a8
x20: ffffff80831000a8 x19: ffffff8083100070 x18: 00000000ffff0a00
x17: 000000002f7254f1 x16: 0000000000000100 x15: 0000000000000000
x14: 0000000000000000 x13: 0000000000000000 x12: 0000000000000000
x11: 000000000001f0b8 x10: ffffffc00931f0b8 x9 : 0000000000000000
x8 : 0000000000000000 x7 : fefefefefeff2f60 x6 : 0000808080808080
x5 : 0000000000000000 x4 : 8080808080800000 x3 : ffffff80d2d4ee28
x2 : ffffff808c1d6e40 x1 : 0000000000000000 x0 : ffffff8083100070
Kernel panic - not syncing: Asynchronous SError Interrupt
CPU: 0 PID: 3595 Comm: mmdata_mgr Not tainted 5.17.1+ #166
Hardware name: Google Lazor (rev1 - 2) with LTE (DT)
Call trace:
dump_backtrace+0xf4/0x114
show_stack+0x24/0x30
dump_stack_lvl+0x64/0x7c
dump_stack+0x18/0x38
panic+0x150/0x38c
nmi_panic+0x88/0xa0
arm64_serror_panic+0x74/0x80
do_serror+0x0/0x80
do_serror+0x58/0x80
el1h_64_error_handler+0x34/0x4c
el1h_64_error+0x78/0x7c
mutex_lock+0x4c/0x80
__gsi_channel_start+0x50/0x17c
gsi_channel_start+0x54/0x90
ipa_endpoint_enable_one+0x34/0xc0
ipa_open+0x4c/0x120
Remove all IP0 resource management from the interconnect driver so that
clk-rpmh is the sole owner. This fixes the issue by preventing the
interconnect driver from overwriting the IP0 resource data that the
clk-rpmh driver wrote.
Cc: Alex Elder <elder@linaro.org>
Cc: Bjorn Andersson <bjorn.andersson@linaro.org>
Cc: Taniya Das <quic_tdas@quicinc.com>
Cc: Mike Tipton <quic_mdtipton@quicinc.com>
Fixes: b95b668eaa ("interconnect: qcom: icc-rpmh: Add BCMs to commit list in pre_aggregate")
Fixes: bcd63d222b ("clk: qcom: rpmh: Add IPA clock for SC7180")
Fixes: 7d3b0b0d81 ("interconnect: qcom: Use icc_sync_state")
Signed-off-by: Stephen Boyd <swboyd@chromium.org>
Tested-by: Alex Elder <elder@linaro.org>
Reviewed-by: Alex Elder <elder@linaro.org>
Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Link: https://lore.kernel.org/r/20220412220033.1273607-2-swboyd@chromium.org
Signed-off-by: Georgi Djakov <djakov@kernel.org>
Booting msm8939 on tip-of-tree I encountered the following error.
[ 1.212340] qnoc-msm8939 580000.interconnect_mm: can't request region for resource [mem 0x00580000-0x0059407f]
[ 1.212391] qnoc-msm8939 580000.interconnect_mm: Cannot ioremap interconnect bus resource
[ 1.221524] qnoc-msm8939: probe of 580000.interconnect_mm failed with error -16
Initially I thought this was a bug with the interconnect driver but,
examining it a bit more I realized the DTS I was working with based on
downstream, declares snoc and snoc_mm as existing at the same address
range.
When we were developing the DTS for 8939 we weren't using the common rpm
interconnect driver so we never saw the ioremap collision.
Taking a hard look at the qcom documentation as well as the downstream code
we see that yes downstream declares snoc and snoc_mm separately but, also
at the same overlapping address.
The qcom documentation for performance points for msm8936/msm8939 snoc,
deliniates snoc_mm as simply two new performance-points i.e. a faster GPLL0
vote associated with new multi-media devices attached to the snoc.
In other words the snoc had two new RPM vote indices added to it, to
represent the higher performance clocks, should one of the multi-media IP
blocks call for it.
We can fix the ioremap collision and still represent the two higher
performance point clock votes by coalsecing snoc and snoc_mm into snoc. The
DTS clock references will take care of the appropriate votes.
V2:
Made snoc-mm into a child of snoc - Dmitry
Removes redundant msm8939_snoc_mm_regmap_config - bod
Link: https://lore.kernel.org/r/20220129032735.2410936-1-bryan.odonoghue@linaro.org
Signed-off-by: Georgi Djakov <djakov@kernel.org>
Booting tip-of-tree on msm8939 we find the following error caused by our
modelling of snoc and snoc_mm as peer devices with the same address space.
[ 1.212340] qnoc-msm8939 580000.interconnect_mm: can't request region for resource [mem 0x00580000-0x0059407f]
[ 1.212391] qnoc-msm8939 580000.interconnect_mm: Cannot ioremap interconnect bus resource
[ 1.221524] qnoc-msm8939: probe of 580000.interconnect_mm failed with error -16
Declaring snoc_mm as a child device of snoc mitigates the fault and is
consistent with a similar extant implementation in qcm2290.
Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Link: https://lore.kernel.org/r/20220129032735.2410936-3-bryan.odonoghue@linaro.org
Signed-off-by: Georgi Djakov <djakov@kernel.org>
Add support for QCM2290 including a few prep changes.
* icc-qcm2290
interconnect: icc-rpm: Define ICC device type
interconnect: icc-rpm: Add QNOC type QoS support
interconnect: icc-rpm: Support child NoC device probe
dt-bindings: interconnect: Add Qualcomm QCM2290 NoC support
interconnect: qcom: Add QCM2290 driver support
Link: https://lore.kernel.org/r/20211215002324.1727-1-shawn.guo@linaro.org
Signed-off-by: Georgi Djakov <djakov@kernel.org>
It adds interconnect driver support for QCM2290 platform. The topology
consists of 3 NoCs: BIMC, Config NoC (CNOC) and System NoC (SNOC). SNOC
is a QCOM_ICC_QNOC type device, as well as its 3 virtual child devices,
QUP, MMNRT and MMRT. QUP is owned by RPM and thus has no .regmap_cfg,
while the other 2 share the same .regmap_cfg with SNOC (parent).
Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
Link: https://lore.kernel.org/r/20211215002324.1727-6-shawn.guo@linaro.org
Signed-off-by: Georgi Djakov <djakov@kernel.org>
As shown in downstream DT[1], the System NoC of QCM2290 is modelled
using 4 fab/noc devices: sys_noc + qup_virt + mmnrt_virt + mmrt_virt.
Among those 3 virtual devices, qup is owned by RPM and has no regmap
resource, while mmnrt and mmrt are owned by AP and share the same
regmap as sys_noc. So it's logical to represent these virtual devices
as child nodes of sys_noc in DT, so that such configuration can be
supported with a couple of changes on qnoc_probe():
- If there are child nodes, populate them.
- If the device descriptor has .regmap_cfg but there is no IOMEM
resource for the device, use parent's regmap.
[1] https://android.googlesource.com/kernel/msm-extra/devicetree/+/refs/tags/android-11.0.0_r0.56/qcom/scuba-bus.dtsi
Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
Link: https://lore.kernel.org/r/20211215002324.1727-4-shawn.guo@linaro.org
Signed-off-by: Georgi Djakov <djakov@kernel.org>
This series adds a driver for interconnects on MSM8996. This fixes some rare display underflows
and provides a slight heat reduction.
* icc-msm8996
dt-bindings: interconnect: Combine SDM660 bindings into RPM schema
interconnect: icc-rpm: Add support for bus power domain
dt-bindings: interconnect: Add Qualcomm MSM8996 DT bindings
interconnect: qcom: Add MSM8996 interconnect provider driver
Link: https://lore.kernel.org/r/20211021132329.234942-1-y.oudjana@protonmail.com
Signed-off-by: Georgi Djakov <djakov@kernel.org>
Using icc-rpm on ARM32 currently results in clk_set_rate() errors during
boot, e.g. "bus clk_set_rate error: -22". This is very similar to commit
7381e27b1e ("interconnect: qcom: msm8974: Prevent integer overflow in rate")
where the u64 is converted to a signed long during clock rate rounding,
resulting in an overflow on 32-bit platforms.
Let's fix it similarly by making sure that the rate does not exceed
LONG_MAX. Such high clock rates will surely result in the maximum
frequency of the bus anyway.
Signed-off-by: Stephan Gerhold <stephan@gerhold.net>
Link: https://lore.kernel.org/r/20211206114542.45325-1-stephan@gerhold.net
Signed-off-by: Georgi Djakov <djakov@kernel.org>
We're only adding BCMs to the commit list in aggregate(), but there are
cases where pre_aggregate() is called without subsequently calling
aggregate(). In particular, in icc_sync_state() when a node with initial
BW has zero requests. Since BCMs aren't added to the commit list in
these cases, we don't actually send the zero BW request to HW. So the
resources remain on unnecessarily.
Add BCMs to the commit list in pre_aggregate() instead, which is always
called even when there are no requests.
Signed-off-by: Mike Tipton <mdtipton@codeaurora.org>
[georgi: remove icc_sync_state for platforms with incomplete support]
Link: https://lore.kernel.org/r/20211125174751.25317-1-djakov@kernel.org
Signed-off-by: Georgi Djakov <djakov@kernel.org>
This patch series merges support for AP-owned and bus QoS from SDM660
into common code (icc-rpm.c). MSM8916 and MSM8939 support code is
extended to support these features. As I was touching these drivers, per
Bjorn's suggestion expand DEFINE_QNODE macros (which makes adding
QoS support much easier to review).
* icc-rpm
interconnect: icc-rpm: move bus clocks handling into qnoc_probe
interconnect: sdm660: expand DEFINE_QNODE macros
interconnect: sdm660: drop default/unused values
interconnect: sdm660: merge common code into icc-rpm
interconnect: icc-rpm: add support for QoS reg offset
interconnect: msm8916: expand DEFINE_QNODE macros
interconnect: msm8916: add support for AP-owned nodes
interconnect: msm8939: expand DEFINE_QNODE macros
interconnect: msm8939: add support for AP-owned nodes
interconnect: qcs404: expand DEFINE_QNODE macros
interconnect: qcom: drop DEFINE_QNODE macro
Link: https://lore.kernel.org/r/20210903232421.1384199-1-dmitry.baryshkov@linaro.org
Signed-off-by: Georgi Djakov <djakov@kernel.org>
Georgi writes:
interconnect changes for 5.15
Here are changes for the 5.15-rc1 merge window consisting of interconnect
core and driver updates.
Framework change:
- Add sanity check to detect if node is already added to provider.
Driver changes:
- RPMh drivers probe function consolidation
- Add driver for SC8180x platforms
- Add support for SC8180x OSM L3
- Use driver-specific naming in OSM L3
Signed-off-by: Georgi Djakov <djakov@kernel.org>
* tag 'icc-5.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/djakov/icc:
interconnect: qcom: osm-l3: Use driver-specific naming
interconnect: qcom: osm-l3: Add sc8180x support
dt-bindings: interconnect: Add SC8180x to OSM L3 DT binding
interconnect: qcom: Add SC8180x providers
dt-bindings: interconnect: Add Qualcomm SC8180x DT bindings
interconnect: Sanity check that node isn't already on list
interconnect: qcom: icc-rpmh: Consolidate probe functions
This reverts commit f84f5b6f72, which is
causing regressions on some platforms, preventing them to boot or do a
clean reboot. This is because the above commit is sending also all the
zero bandwidth requests to turn off any resources that might be enabled
unnecessarily, but currently this may turn off interconnects that are
enabled by default, but with no consumer to keep them on.
Let's revert this for now as some platforms are not ready for such
change yet. In the future we can introduce some _ignore_unused option
that could keep also the unused resources on platforms that have only
partial interconnect support and also add .shutdown callbacks to deal
with disabling the resources in the right order.
Reported-by: Stephen Boyd <swboyd@chromium.org>
Reported-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Link: https://lore.kernel.org/r/CAE-0n52iVgX0JjjnYi=NDg49xP961p=+W5R2bmO+2xwRceFhfA@mail.gmail.com
Signed-off-by: Georgi Djakov <djakov@kernel.org>
In situations were the developer screws up by e.g. not giving the OSM
nodes unique identifiers the interconnect framework might mix up nodes
between the OSM L3 provider and e.g. the RPMh provider.
The resulting callstack contains "qcom_icc_set", which is not unique to
the OSM L3 provider driver. Once the faulting qcom_icc_set() is
identified it's further confusing that "qcom_icc_node" is different
between the different drivers.
To avoid this confusion, rename the node struct and the setter in the
OSM L3 driver to include "osm_l3" in their names.
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Tested-by: Steev Klimaszewski <steev@kali.org>
Reviewed-by: Stephen Boyd <swboyd@chromium.org>
Link: https://lore.kernel.org/r/20210725031414.3961227-1-bjorn.andersson@linaro.org
Signed-off-by: Georgi Djakov <djakov@kernel.org>
We're only adding BCMs to the commit list in aggregate(), but there are
cases where pre_aggregate() is called without subsequently calling
aggregate(). In particular, in icc_sync_state() when a node with initial
BW has zero requests. Since BCMs aren't added to the commit list in
these cases, we don't actually send the zero BW request to HW. So the
resources remain on unnecessarily.
Add BCMs to the commit list in pre_aggregate() instead, which is always
called even when there are no requests.
Fixes: 976daac4a1 ("interconnect: qcom: Consolidate interconnect RPMh support")
Signed-off-by: Mike Tipton <mdtipton@codeaurora.org>
Link: https://lore.kernel.org/r/20210721175432.2119-5-mdtipton@codeaurora.org
Signed-off-by: Georgi Djakov <djakov@kernel.org>
We currently only enforce BW floors for a subset of nodes in a path.
All BCMs that need updating are queued in the pre_aggregate/aggregate
phase. The first set() commits all queued BCMs and subsequent set()
calls short-circuit without committing anything. Since the floor BW
isn't set in sum_avg/max_peak until set(), then some BCMs are committed
before their associated nodes reflect the floor.
Set the floor as each node is being aggregated. This ensures that all
all relevant floors are set before the BCMs are committed.
Fixes: 266cd33b59 ("interconnect: qcom: Ensure that the floor bandwidth value is enforced")
Signed-off-by: Mike Tipton <mdtipton@codeaurora.org>
Link: https://lore.kernel.org/r/20210721175432.2119-4-mdtipton@codeaurora.org
[georgi: Removed unused variable]
Signed-off-by: Georgi Djakov <djakov@kernel.org>
Broken interconnect providers might add the same node multiple times or
in multiple providers, which causes strange errors as the provider's
node list is later traversed.
Detect that a node already has an associated provider, complain and
reject the addition of the node, to aid the developer.
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Link: https://lore.kernel.org/r/20210625234903.1324755-1-bjorn.andersson@linaro.org
Signed-off-by: Georgi Djakov <djakov@kernel.org>
Georgi writes:
interconnect changes for 5.14
Here are changes for the 5.14-rc1 merge window consisting of interconnect
driver updates.
Driver changes:
- New driver for SC7280 platforms.
Signed-off-by: Georgi Djakov <djakov@kernel.org>
* tag 'icc-5.14-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/djakov/icc:
interconnect: qcom: Add SC7280 interconnect provider driver
dt-bindings: interconnect: Add Qualcomm SC7280 DT bindings