summaryrefslogtreecommitdiffstats
path: root/drivers/soc/qcom/rpmh-rsc.c
Commit message (Collapse)AuthorAgeFilesLines
* soc: qcom: rpmh-rsc: Sleep waiting for tcs slots to be freeStephen Boyd2020-09-101-61/+54
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The busy loop in rpmh_rsc_send_data() is written with the assumption that the udelay will be preempted by the tcs_tx_done() irq handler when the TCS slots are all full. This doesn't hold true when the calling thread is an irqthread and the tcs_tx_done() irq is also an irqthread. That's because kernel irqthreads are SCHED_FIFO and thus need to voluntarily give up priority by calling into the scheduler so that other threads can run. I see RCU stalls when I boot with irqthreads on the kernel commandline because the modem remoteproc driver is trying to send an rpmh async message from an irqthread that needs to give up the CPU for the rpmh irqthread to run and clear out tcs slots. rcu: INFO: rcu_preempt self-detected stall on CPU rcu: 0-....: (1 GPs behind) idle=402/1/0x4000000000000002 softirq=2108/2109 fqs=4920 (t=21016 jiffies g=2933 q=590) Task dump for CPU 0: irq/11-smp2p R running task 0 148 2 0x00000028 Call trace: dump_backtrace+0x0/0x154 show_stack+0x20/0x2c sched_show_task+0xfc/0x108 dump_cpu_task+0x44/0x50 rcu_dump_cpu_stacks+0xa4/0xf8 rcu_sched_clock_irq+0x7dc/0xaa8 update_process_times+0x30/0x54 tick_sched_handle+0x50/0x64 tick_sched_timer+0x4c/0x8c __hrtimer_run_queues+0x21c/0x36c hrtimer_interrupt+0xf0/0x22c arch_timer_handler_phys+0x40/0x50 handle_percpu_devid_irq+0x114/0x25c __handle_domain_irq+0x84/0xc4 gic_handle_irq+0xd0/0x178 el1_irq+0xbc/0x180 save_return_addr+0x18/0x28 return_address+0x54/0x88 preempt_count_sub+0x40/0x88 _raw_spin_unlock_irqrestore+0x4c/0x6c ___ratelimit+0xd0/0x128 rpmh_rsc_send_data+0x24c/0x378 __rpmh_write+0x1b0/0x208 rpmh_write_async+0x90/0xbc rpmhpd_send_corner+0x60/0x8c rpmhpd_aggregate_corner+0x8c/0x124 rpmhpd_set_performance_state+0x8c/0xbc _genpd_set_performance_state+0xdc/0x1b8 dev_pm_genpd_set_performance_state+0xb8/0xf8 q6v5_pds_disable+0x34/0x60 [qcom_q6v5_mss] qcom_msa_handover+0x38/0x44 [qcom_q6v5_mss] q6v5_handover_interrupt+0x24/0x3c [qcom_q6v5] handle_nested_irq+0xd0/0x138 qcom_smp2p_intr+0x188/0x200 irq_thread_fn+0x2c/0x70 irq_thread+0xfc/0x14c kthread+0x11c/0x12c ret_from_fork+0x10/0x18 This busy loop naturally lends itself to using a wait queue so that each thread that tries to send a message will sleep waiting on the waitqueue and only be woken up when a free slot is available. This should make things more predictable too because the scheduler will be able to sleep tasks that are waiting on a free tcs instead of the busy loop we currently have today. Reviewed-by: Maulik Shah <mkshah@codeaurora.org> Reviewed-by: Douglas Anderson <dianders@chromium.org> Tested-by: Stanimir Varbanov <stanimir.varbanov@linaro.org> Cc: Douglas Anderson <dianders@chromium.org> Cc: Maulik Shah <mkshah@codeaurora.org> Cc: Lina Iyer <ilina@codeaurora.org> Signed-off-by: Stephen Boyd <swboyd@chromium.org> Link: https://lore.kernel.org/r/20200724211711.810009-1-sboyd@kernel.org Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
* soc: qcom: rpmh-rsc: Don't use ktime for timeout in write_tcs_reg_sync()Douglas Anderson2020-06-241-5/+13
| | | | | | | | | | | | | | | | | | | | | | | | The write_tcs_reg_sync() may be called after timekeeping is suspended so it's not OK to use ktime. The readl_poll_timeout_atomic() macro implicitly uses ktime. This was causing a warning at suspend time. Change to just loop 1000000 times with a delay of 1 us between loops. This may give a timeout of more than 1 second but never less and is safe even if timekeeping is suspended. NOTE: I don't have any actual evidence that we need to loop here. It's possibly that all we really need to do is just read the value back to ensure that the pipes are cleaned and the looping/comparing is totally not needed. I never saw the loop being needed in my tests. However, the loop shouldn't hurt. Reviewed-by: Stephen Boyd <sboyd@kernel.org> Reviewed-by: Maulik Shah <mkshah@codeaurora.org> Fixes: 91160150aba0 ("soc: qcom: rpmh-rsc: Timeout after 1 second in write_tcs_reg_sync()") Reported-by: Maulik Shah <mkshah@codeaurora.org> Signed-off-by: Douglas Anderson <dianders@chromium.org> Link: https://lore.kernel.org/r/20200528074530.1.Ib86e5b406fe7d16575ae1bb276d650faa144b63c@changeid Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
* soc: qcom: rpmh-rsc: Set suppress_bind_attrs flagMaulik Shah2020-06-221-0/+1
| | | | | | | | | | | | | | | rpmh-rsc driver is fairly core to system and should not be removable once its probed. However it allows to unbind driver from sysfs using below command which results into a crash on sc7180. echo 18200000.rsc > /sys/bus/platform/drivers/rpmh/unbind Lets prevent unbind at runtime by setting suppress_bind_attrs flag. Reviewed-by: Stephen Boyd <swboyd@chromium.org> Signed-off-by: Maulik Shah <mkshah@codeaurora.org> Link: https://lore.kernel.org/r/1592808805-2437-1-git-send-email-mkshah@codeaurora.org Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
* Revert "soc: qcom: rpmh: Allow RPMH driver to be loaded as a module"Bjorn Andersson2020-05-171-5/+0
| | | | | | | | | | | | | | Attempting to compile rpmh-rsc.c as a module with TRACING enabled causes a build error as no _rcuidle function is generated for tracepoints when CONFIG_MODULE is set. Attempts has been made, but no resolution has been agreed upon, so lets revert this commit for now. This reverts commit 1d3c6f86fd3f8b88c707f56d8c3f94e014b40e83. Reported-by: Stephen Rothwell <sfr@canb.auug.org.au> Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
* soc: qcom: rpmh-rsc: Remove the pm_lockDouglas Anderson2020-05-151-29/+46
| | | | | | | | | | | | | | | | | | | | | | | It has been postulated that the pm_lock is bad for performance because a CPU currently running rpmh_flush() could block other CPUs from coming out of idle. Similarly CPUs coming out of / going into idle all need to contend with each other for the spinlock just to update the variable tracking who's in PM. Let's optimize this a bit. Specifically: - Use a count rather than a bitmask. This is faster to access and also means we can use the atomic_inc_return() function to really detect who the last one to enter PM was. - Accept that it's OK if we race and are doing the flush (because we think we're last) while another CPU is coming out of idle. As long as we block that CPU if/when it tries to do an active-only transfer we're OK. Signed-off-by: Douglas Anderson <dianders@chromium.org> Reviewed-by: Stephen Boyd <swboyd@chromium.org> Link: https://lore.kernel.org/r/20200504104917.v6.5.I295cb72bc5334a2af80313cbe97cb5c9dcb1442c@changeid Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
* soc: qcom: rpmh-rsc: Simplify locking by eliminating the per-TCS lockDouglas Anderson2020-05-151-30/+25
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The rpmh-rsc code had both a driver-level lock (sometimes referred to in comments as drv->lock) and a lock per-TCS. The idea was supposed to be that there would be times where you could get by with just locking a TCS lock and therefor other RPMH users wouldn't be blocked. The above didn't work out so well. Looking at tcs_write() the bigger drv->lock was held for most of the function anyway. Only the __tcs_buffer_write() and __tcs_set_trigger() calls were called without holding the drv->lock. It actually turns out that in tcs_write() we don't need to hold the drv->lock for those function calls anyway even if the per-TCS lock isn't there anymore. From the newly added comments in the code, this is because: - We marked "tcs_in_use" under lock. - Once "tcs_in_use" has been marked nobody else could be writing to these registers until the interrupt goes off. - The interrupt can't go off until we trigger w/ the last line of __tcs_set_trigger(). Thus, from a tcs_write() point of view, the per-TCS lock was useless. Looking at rpmh_rsc_write_ctrl_data(), only the per-TCS lock was held. It turns out, though, that this function already needs to be called with the equivalent of the drv->lock held anyway (we either need to hold drv->lock as we will in a future patch or we need to know no other CPUs could be running as happens today). Specifically rpmh_rsc_write_ctrl_data() might be writing to a TCS that has been borrowed for writing an active transation but it never checks this. Let's eliminate this extra overhead and avoid possible AB BA locking headaches. Suggested-by: Maulik Shah <mkshah@codeaurora.org> Signed-off-by: Douglas Anderson <dianders@chromium.org> Reviewed-by: Stephen Boyd <swboyd@chromium.org> Link: https://lore.kernel.org/r/20200504104917.v6.4.Ib8dccfdb10bf6b1fb1d600ca1c21d9c0db1ef746@changeid Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
* soc: qcom: rpmh-rsc: We aren't notified of our own failure w/ NOTIFY_BADDouglas Anderson2020-05-151-0/+4
| | | | | | | | | | | | | | | | | | | When a PM Notifier returns NOTIFY_BAD it doesn't get called with CPU_PM_ENTER_FAILED. It only get called for CPU_PM_ENTER_FAILED if someone else (further down the notifier chain) returns NOTIFY_BAD. Handle this case by taking our CPU out of the list of ones that have entered PM. Without this it's possible we could detect that the last CPU went down (and we would flush) even if some CPU was alive. That's not good since our flushing routines currently assume they're running on the last CPU for mutual exclusion. Fixes: 985427f997b6 ("soc: qcom: rpmh: Invoke rpmh_flush() for dirty caches") Signed-off-by: Douglas Anderson <dianders@chromium.org> Reviewed-by: Maulik Shah <mkshah@codeaurora.org> Reviewed-by: Stephen Boyd <swboyd@chromium.org> Link: https://lore.kernel.org/r/20200504104917.v6.2.I1927d1bca2569a27b2d04986baf285027f0818a2@changeid Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
* soc: qcom: rpmh-rsc: Correctly ignore CPU_CLUSTER_PM notificationsDouglas Anderson2020-05-151-0/+3
| | | | | | | | | | | | | | | | | | | | | Our switch statement doesn't have entries for CPU_CLUSTER_PM_ENTER, CPU_CLUSTER_PM_ENTER_FAILED, and CPU_CLUSTER_PM_EXIT and doesn't have a default. This means that we'll try to do a flush in those cases but we won't necessarily be the last CPU down. That's not so ideal since our (lack of) locking assumes we're on the last CPU. Luckily this isn't as big a problem as you'd think since (at least on the SoC I tested) we don't get these notifications except on full system suspend. ...and on full system suspend we get them on the last CPU down. That means that the worst problem we hit is flushing twice. Still, it's good to make it correct. Reviewed-by: Stephen Boyd <swboyd@chromium.org> Fixes: 985427f997b6 ("soc: qcom: rpmh: Invoke rpmh_flush() for dirty caches") Reported-by: Stephen Boyd <swboyd@chromium.org> Signed-off-by: Douglas Anderson <dianders@chromium.org> Link: https://lore.kernel.org/r/20200504104917.v6.1.Ic7096b3b9b7828cdd41cd5469a6dee5eb6abf549@changeid Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
* soc: qcom: rpmh-rsc: Timeout after 1 second in write_tcs_reg_sync()Douglas Anderson2020-05-121-5/+7
| | | | | | | | | | If our data still isn't there after 1 second, shout and give up. Reported-by: Joe Perches <joe@perches.com> Signed-off-by: Douglas Anderson <dianders@chromium.org> Reviewed-by: Stephen Boyd <swboyd@chromium.org> Link: https://lore.kernel.org/r/20200415095953.v3.2.I8550512081c89ec7a545018a7d2d9418a27c1a7a@changeid Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
* soc: qcom: rpmh-rsc: Factor "tcs_reg_addr" and "tcs_cmd_addr" calculationDouglas Anderson2020-05-121-15/+26
| | | | | | | | | | | We can make some of the register access functions more readable by factoring out the calculations a little bit. Suggested-by: Joe Perches <joe@perches.com> Signed-off-by: Douglas Anderson <dianders@chromium.org> Reviewed-by: Stephen Boyd <swboyd@chromium.org> Link: https://lore.kernel.org/r/20200415095953.v3.1.Ic70288f256ff0be65cac6a600367212dfe39f6c9@changeid Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
* soc: qcom: rpmh: Allow RPMH driver to be loaded as a moduleJohn Stultz2020-04-141-0/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | This patch allow the rpmh driver to be loaded as a permenent module. Meaning it can be loaded from a module, but then cannot be unloaded. Ideally, it would include a remove hook and related logic, but the rpmh driver is fairly core to the system, so once its loaded with almost anythign else to get the system to go, the dependencies are not likely to ever also be removed. So making it a permenent module at least improves things slightly over requiring it to be a built in driver. Acked-by: Saravana Kannan <saravanak@google.com> Cc: Todd Kjos <tkjos@google.com> Cc: Saravana Kannan <saravanak@google.com> Cc: Andy Gross <agross@kernel.org> Cc: Bjorn Andersson <bjorn.andersson@linaro.org> Cc: Rajendra Nayak <rnayak@codeaurora.org> Cc: linux-arm-msm@vger.kernel.org Tested-by: Bjorn Andersson <bjorn.andersson@linaro.org> Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org> Signed-off-by: John Stultz <john.stultz@linaro.org> Link: https://lore.kernel.org/r/20200326224459.105170-3-john.stultz@linaro.org Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
* soc: qcom: rpmh-rsc: read_tcs_reg()/write_tcs_reg() are not for IRQDouglas Anderson2020-04-131-5/+6
| | | | | | | | | | | | | | | The RSC_DRV_IRQ_ENABLE, RSC_DRV_IRQ_STATUS, and RSC_DRV_IRQ_CLEAR registers are not part of TCS 0. Let's not pretend that they are by using read_tcs_reg() and write_tcs_reg() and passing a bogus tcs_id of 0. We could introduce a new wrapper for these registers but it wouldn't buy us much. Let's just read/write directly. Signed-off-by: Douglas Anderson <dianders@chromium.org> Reviewed-by: Maulik Shah <mkshah@codeaurora.org> Reviewed-by: Stephen Boyd <swboyd@chromium.org> Tested-by: Maulik Shah <mkshah@codeaurora.org> Link: https://lore.kernel.org/r/20200413100321.v4.10.I2adf93809c692d0b673e1a86ea97c45644aa8d97@changeid Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
* soc: qcom: rpmh-rsc: Caller handles tcs_invalidate() exclusivityDouglas Anderson2020-04-131-25/+13
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Auditing tcs_invalidate() made me worried. Specifically I saw that it used spin_lock(), not spin_lock_irqsave(). That always worries me unless I can trace for sure that I'm in the interrupt handler or that someone else already disabled interrupts. Looking more at it, there is actually no reason for these locks anyway. Specifically the only reason you'd ever call rpmh_rsc_invalidate() is if you cared that the sleep/wake TCSes were empty. That means that they need to continue to be empty even after rpmh_rsc_invalidate() returns. The only way that can happen is if the caller already has done something to keep all other RPMH users out. It should be noted that even though the caller is only worried about making sleep/wake TCSes empty, they also need to worry about stopping active-only transfers if they need to handle the case where active-only transfers might borrow the wake TCS. At the moment rpmh_rsc_invalidate() is only called in PM code from the last CPU. If that later changes the caller will still need to solve the above problems themselves, so these locks will never be useful. Continuing to audit tcs_invalidate(), I found a bug. The function didn't properly check for a borrowed TCS if we hadn't recently written anything into the TCS. Specifically, if we've never written to the WAKE_TCS (or we've flushed it recently) then tcs->slots is empty. We'll early-out and we'll never call tcs_is_free(). I thought about fixing this bug by either deleting the early check for bitmap_empty() or possibly only doing it if we knew we weren't on a TCS that could be borrowed. However, I think it's better to just delete the checks. As argued above it's up to the caller to make sure that all other users of RPMH are quiet before tcs_invalidate() is called. Since callers need to handle the zero-active-TCS case anyway that means they need to make sure that the active-only transfers are quiet before calling too. The one way tcs_invalidate() gets called today is through rpmh_rsc_cpu_pm_callback() which calls rpmh_rsc_ctrlr_is_busy() to handle this. When we have another path to get to tcs_invalidate() it will also need to come up with something similar and it won't need this extra check either. If we later find some code path that actually needs this check back in (and somehow manages to be race free) we can always add it back in. Signed-off-by: Douglas Anderson <dianders@chromium.org> Reviewed-by: Maulik Shah <mkshah@codeaurora.org> Reviewed-by: Stephen Boyd <swboyd@chromium.org> Tested-by: Maulik Shah <mkshah@codeaurora.org> Link: https://lore.kernel.org/r/20200413100321.v4.9.I07c1f70e0e8f2dc0004bd38970b4e258acdc773e@changeid Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
* soc: qcom: rpmh-rsc: Don't double-check rpmh payloadDouglas Anderson2020-04-131-17/+1
| | | | | | | | | | | | | | The calls rpmh_rsc_write_ctrl_data() and rpmh_rsc_send_data() are only ever called from rpmh.c. We know that rpmh.c already error checked the message. There's no reason to do it again in rpmh-rsc. Suggested-by: Maulik Shah <mkshah@codeaurora.org> Signed-off-by: Douglas Anderson <dianders@chromium.org> Reviewed-by: Maulik Shah <mkshah@codeaurora.org> Reviewed-by: Stephen Boyd <swboyd@chromium.org> Tested-by: Maulik Shah <mkshah@codeaurora.org> Link: https://lore.kernel.org/r/20200413100321.v4.8.I8e187cdfb7a31f5bb7724f1f937f2862ee464a35@changeid Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
* soc: qcom: rpmh-rsc: tcs_is_free() can just check tcs_in_useDouglas Anderson2020-04-131-3/+1
| | | | | | | | | | | | | | | | | tcs_is_free() had two checks in it: does the software think that the TCS is free and does the hardware think that the TCS is free. I couldn't figure out in which case the hardware could think that a TCS was in-use but software thought it was free. Apparently there is no case and the extra check can be removed. This apparently has already been done in a downstream patch. Suggested-by: Maulik Shah <mkshah@codeaurora.org> Signed-off-by: Douglas Anderson <dianders@chromium.org> Reviewed-by: Maulik Shah <mkshah@codeaurora.org> Reviewed-by: Stephen Boyd <swboyd@chromium.org> Tested-by: Maulik Shah <mkshah@codeaurora.org> Link: https://lore.kernel.org/r/20200413100321.v4.7.Icf2213131ea652087f100129359052c83601f8b0@changeid Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
* soc: qcom: rpmh-rsc: A lot of commentsDouglas Anderson2020-04-131-15/+207
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | I've been pouring through the rpmh-rsc code and trying to understand it. Document everything to the best of my ability. All documentation here is strictly from code analysis--no actual knowledge of the hardware was used. If something is wrong in here I either misunderstood the code, had a typo, or the code has a bug in it leading to my incorrect understanding. In a few places here I have documented things that don't make tons of sense. A future patch will try to address this. While this means I'm adding comments / todos and then later fixing them in the series, it seemed more urgent to get things documented first so that people could understand the later patches. Any comments I adjusted I also tried to make match kernel-doc better. Specifically: - kernel-doc says do not leave a blank line between the function description and the arguments - kernel-doc examples always have things starting w/ a capital and ending with a period. This should be a no-op. It's just comment changes. Signed-off-by: Douglas Anderson <dianders@chromium.org> Reviewed-by: Maulik Shah <mkshah@codeaurora.org> Reviewed-by: Stephen Boyd <swboyd@chromium.org> Link: https://lore.kernel.org/r/20200413100321.v4.6.I52653eb85d7dc8981ee0dafcd0b6cc0f273e9425@changeid Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
* soc: qcom: rpmh-rsc: Kill cmd_cache and find_match() with fireDouglas Anderson2020-04-131-47/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The "cmd_cache" in RPMH wasn't terribly sensible. Specifically: - The current code doesn't really detect "conflicts" properly any case where the sequence being checked has more than one entry. One simple way to see this in the current code is that if cmd[0].addr isn't found then cmd[1].addr is never checked. - The code attempted to use the "cmd_cache" to update an existing message in a sleep/wake TCS with new data. The goal appeared to be to update part of a TCS while leaving the rest of the TCS alone. We never actually do this. We always fully invalidate and re-write everything. - If/when we try to optimize things to not fully invalidate / re-write every time we update the TCSes we'll need to think it through very carefully. Specifically requirement of find_match() that the new sequence of addrs must match exactly the old sequence of addrs seems inflexible. It's also not documented in rpmh_write() and rpmh_write_batch(). In any case, if we do decide to require updates to keep the exact same sequence and length then presumably the API and data structures should be updated to understand groups more properly. The current algorithm doesn't really keep track of the length of the old sequence and there are several boundary-condition bugs because of that. Said another way: if we decide to do something like this in the future we should start from scratch and thus find_match() isn't useful to keep around. This patch isn't quite a no-op. Specifically: - It should be a slight performance boost of not searching through so many arrays. - The old code would have done something useful in one case: it would allow someone calling rpmh_write() to override the data that came from rpmh_write_batch(). I don't believe that actually happens in reality. Signed-off-by: Douglas Anderson <dianders@chromium.org> Reviewed-by: Maulik Shah <mkshah@codeaurora.org> Reviewed-by: Stephen Boyd <swboyd@chromium.org> Tested-by: Maulik Shah <mkshah@codeaurora.org> Link: https://lore.kernel.org/r/20200413100321.v4.5.I6d3d0a3ec810dc72ff1df3cbf97deefdcdeb8eef@changeid Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
* soc: qcom: rpmh-rsc: Remove get_tcs_of_type() abstractionDouglas Anderson2020-04-131-12/+5
| | | | | | | | | | | | | | | The get_tcs_of_type() function doesn't provide any value. It's not conceptually difficult to access a value in an array, even if that value is in a structure and we want a pointer to the value. Having the function in there makes me feel like it's doing something fancier like looping or searching. Remove it. Signed-off-by: Douglas Anderson <dianders@chromium.org> Reviewed-by: Maulik Shah <mkshah@codeaurora.org> Reviewed-by: Stephen Boyd <swboyd@chromium.org> Tested-by: Maulik Shah <mkshah@codeaurora.org> Link: https://lore.kernel.org/r/20200413100321.v4.4.Ia348ade7c6ed1d0d952ff2245bc854e5834c8d9a@changeid Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
* soc: qcom: rpmh-rsc: Fold tcs_ctrl_write() into its single callerDouglas Anderson2020-04-131-22/+17
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | I was trying to write documentation for the functions in rpmh-rsc and I got to tcs_ctrl_write(). The documentation for the function would have been: "This is the core of rpmh_rsc_write_ctrl_data(); all the caller does is error-check and then call this". Having the error checks in a separate function doesn't help for anything since: - There are no other callers that need to bypass the error checks. - It's less documenting. When I read tcs_ctrl_write() I kept wondering if I need to handle cases other than ACTIVE_ONLY or cases with more commands than could fit in a TCS. This is obvious when the error checks and code are together. - The function just isn't that long, so there's no problem understanding the combined function. Things were even more confusing because the two functions names didn't make obvious (at least to me) their relationship. Simplify by folding one function into the other. Signed-off-by: Douglas Anderson <dianders@chromium.org> Reviewed-by: Maulik Shah <mkshah@codeaurora.org> Reviewed-by: Stephen Boyd <swboyd@chromium.org> Tested-by: Maulik Shah <mkshah@codeaurora.org> Link: https://lore.kernel.org/r/20200413100321.v4.3.Ie88ce5ccfc0c6055903ccca5286ae28ed3b85ed3@changeid Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
* soc: qcom: rpmh-rsc: Document the register layout betterDouglas Anderson2020-04-131-5/+74
| | | | | | | | | | | | Perhaps it's just me, it took a really long time to understand what the register layout of rpmh-rsc was just from the #defines. Let's add a bunch of comments describing which blocks are part of other blocks. Signed-off-by: Douglas Anderson <dianders@chromium.org> Reviewed-by: Maulik Shah <mkshah@codeaurora.org> Reviewed-by: Stephen Boyd <swboyd@chromium.org> Link: https://lore.kernel.org/r/20200413100321.v4.2.Iaddc29b72772e6ea381238a0ee85b82d3903e5f2@changeid Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
* soc: qcom: rpmh-rsc: Clean code reading/writing TCS regs/cmdsDouglas Anderson2020-04-131-14/+19
| | | | | | | | | | | | | | | | | | | This patch makes two changes, both of which should be no-ops: 1. Make read_tcs_reg() / read_tcs_cmd() symmetric to write_tcs_reg() / write_tcs_cmd(). 2. Change the order of operations in the above functions to make it more obvious to me what the math is doing. Specifically first you want to find the right TCS, then the right register, and then multiply by the command ID if necessary. Signed-off-by: Douglas Anderson <dianders@chromium.org> Reviewed-by: Maulik Shah <mkshah@codeaurora.org> Reviewed-by: Stephen Boyd <swboyd@chromium.org> Tested-by: Maulik Shah <mkshah@codeaurora.org> Link: https://lore.kernel.org/r/20200413100321.v4.1.I1b754137e8089e46cf33fc2ea270734ec3847ec4@changeid Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
* soc: qcom: rpmh-rsc: Allow using free WAKE TCS for active requestMaulik Shah2020-04-131-12/+11
| | | | | | | | | | | | | | | | | | When there are more than one WAKE TCS available and there is no dedicated ACTIVE TCS available, invalidating all WAKE TCSes and waiting for current transfer to complete in first WAKE TCS blocks using another free WAKE TCS to complete current request. Remove rpmh_rsc_invalidate() to happen from tcs_write() when WAKE TCSes is re-purposed to be used for Active mode. Clear only currently used WAKE TCS's register configuration. Fixes: 2de4b8d33eab (drivers: qcom: rpmh-rsc: allow active requests from wake TCS) Signed-off-by: Maulik Shah <mkshah@codeaurora.org> Reviewed-by: Douglas Anderson <dianders@chromium.org> Reviewed-by: Stephen Boyd <swboyd@chromium.org> Link: https://lore.kernel.org/r/1586703004-13674-7-git-send-email-mkshah@codeaurora.org Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
* soc: qcom: rpmh-rsc: Clear active mode configuration for wake TCSRaju P.L.S.S.S.N2020-04-131-23/+54
| | | | | | | | | | | | | | | | | | | For RSCs that have sleep & wake TCS but no dedicated active TCS, wake TCS can be re-purposed to send active requests. Once the active requests are sent and response is received, the active mode configuration needs to be cleared so that controller can use wake TCS for sending wake requests. Introduce enable_tcs_irq() to enable completion IRQ for repurposed TCSes. Fixes: 2de4b8d33eab (drivers: qcom: rpmh-rsc: allow active requests from wake TCS) Signed-off-by: Raju P.L.S.S.S.N <rplsssn@codeaurora.org> [mkshah: call enable_tcs_irq() within drv->lock, update commit message] Signed-off-by: Maulik Shah <mkshah@codeaurora.org> Reviewed-by: Douglas Anderson <dianders@chromium.org> Reviewed-by: Stephen Boyd <swboyd@chromium.org> Link: https://lore.kernel.org/r/1586703004-13674-6-git-send-email-mkshah@codeaurora.org Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
* soc: qcom: rpmh: Invoke rpmh_flush() for dirty cachesMaulik Shah2020-04-131-12/+110
| | | | | | | | | | | | | | | | | Add changes to invoke rpmh flush() from CPU PM notification. This is done when the last the cpu is entering deep CPU idle states and controller is not busy. Controllers that have 'HW solver' mode like display RSC do not need to register for CPU PM notification. They may be in autonomous mode executing low power mode and do not require rpmh_flush() to happen from CPU PM notification. Signed-off-by: Maulik Shah <mkshah@codeaurora.org> Reviewed-by: Douglas Anderson <dianders@chromium.org> Reviewed-by: Stephen Boyd <swboyd@chromium.org> Link: https://lore.kernel.org/r/1586703004-13674-5-git-send-email-mkshah@codeaurora.org Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
* drivers: qcom: rpmh-rsc: Use rcuidle tracepoints for rpmhStephen Boyd2020-03-091-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This tracepoint is hit now that we call into the rpmh code from the cpu idle path. Let's move this to be an rcuidle tracepoint so that we avoid the RCU idle splat below ============================= WARNING: suspicious RCU usage 5.4.10 #68 Tainted: G S ----------------------------- drivers/soc/qcom/trace-rpmh.h:72 suspicious rcu_dereference_check() usage! other info that might help us debug this: RCU used illegally from idle CPU! rcu_scheduler_active = 2, debug_locks = 1 RCU used illegally from extended quiescent state! 5 locks held by swapper/2/0: #0: ffffff81745d6ee8 (&(&genpd->slock)->rlock){+.+.}, at: genpd_lock_spin+0x1c/0x2c #1: ffffff81745da6e8 (&(&genpd->slock)->rlock/1){....}, at: genpd_lock_nested_spin+0x24/0x34 #2: ffffff8174f2ca20 (&(&genpd->slock)->rlock/2){....}, at: genpd_lock_nested_spin+0x24/0x34 #3: ffffff8174f2c300 (&(&drv->client.cache_lock)->rlock){....}, at: rpmh_flush+0x48/0x24c #4: ffffff8174f2c150 (&(&tcs->lock)->rlock){+.+.}, at: rpmh_rsc_write_ctrl_data+0x74/0x270 stack backtrace: CPU: 2 PID: 0 Comm: swapper/2 Tainted: G S 5.4.10 #68 Call trace: dump_backtrace+0x0/0x174 show_stack+0x20/0x2c dump_stack+0xc8/0x124 lockdep_rcu_suspicious+0xe4/0x104 __tcs_buffer_write+0x230/0x2d0 rpmh_rsc_write_ctrl_data+0x210/0x270 rpmh_flush+0x84/0x24c rpmh_domain_power_off+0x78/0x98 _genpd_power_off+0x40/0xc0 genpd_power_off+0x168/0x208 genpd_power_off+0x1e0/0x208 genpd_power_off+0x1e0/0x208 genpd_runtime_suspend+0x1ac/0x220 __rpm_callback+0x70/0xfc rpm_callback+0x34/0x8c rpm_suspend+0x218/0x4a4 __pm_runtime_suspend+0x88/0xac psci_enter_domain_idle_state+0x3c/0xb4 cpuidle_enter_state+0xb8/0x284 cpuidle_enter+0x38/0x4c call_cpuidle+0x3c/0x68 do_idle+0x194/0x260 cpu_startup_entry+0x24/0x28 secondary_start_kernel+0x150/0x15c Acked-by: Ulf Hansson <ulf.hansson@linaro.org> Reviewed-by: Douglas Anderson <dianders@chromium.org> Tested-by: Sai Prakash Ranjan <saiprakash.ranjan@codeaurora.org> Fixes: a65a397f2451 ("cpuidle: psci: Add support for PM domains by using genpd") Reported-by: Sai Prakash Ranjan <saiprakash.ranjan@codeaurora.org> Cc: Ulf Hansson <ulf.hansson@linaro.org> Signed-off-by: Stephen Boyd <swboyd@chromium.org> Link: https://lore.kernel.org/r/20200115013751.249588-1-swboyd@chromium.org Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
* drivers: soc: qcom: rpmh-rsc: Correct check for slot numberMaulik Shah2019-04-091-1/+1
| | | | | | | | | | The return index value from bitmap_find_next_zero_area can be higher than available slot. So correct the check to return error in such case. Signed-off-by: Maulik Shah <mkshah@codeaurora.org> Signed-off-by: Raju P.L.S.S.S.N <rplsssn@codeaurora.org> Reviewed-by: Lina Iyer <ilina@codeaurora.org> Signed-off-by: Andy Gross <agross@kernel.org>
* drivers: qcom: rpmh-rsc: clear wait_for_compl after useLina Iyer2018-09-131-0/+2
| | | | | | | | | | The wait_for_compl register ensures the request sequence is maintained when sending requests from the TCS. Clear the register after sending active request and during invalidate of the sleep and wake TCS. Reported-by: Raju P.L.S.S.S.N <rplsssn@codeaurora.org> Signed-off-by: Lina Iyer <ilina@codeaurora.org> Signed-off-by: Andy Gross <andy.gross@linaro.org>
* drivers: qcom: rpmh: fix unwanted error check for get_tcs_of_type()Raju P.L.S.S.S.N2018-07-211-4/+2
| | | | | | | | | | | | | | | | | | | | | | | The patch fixes the bug reported by Dan Carpenter. It removes the unnecessary err check for ‘tcs’ reported by static checker warning: drivers/soc/qcom/rpmh-rsc.c:111 tcs_invalidate() warn: 'tcs' isn't an ERR_PTR See also: drivers/soc/qcom/rpmh-rsc.c:178 get_tcs_for_msg() warn: 'tcs' isn't an ERR_PTR drivers/soc/qcom/rpmh-rsc.c:180 get_tcs_for_msg() warn: 'tcs' isn't an ERR_PTR https://www.spinics.net/lists/linux-soc/msg04624.html Fixes: 9a3afcf ("drivers: qcom: rpmh-rsc: allow invalidation of sleep/wake TCS") Reported-by: Dan Carpenter <dan.carpenter@oracle.com> Signed-off-by: Raju P.L.S.S.S.N <rplsssn@codeaurora.org> Reviewed-by: Lina Iyer <ilina@codeaurora.org> Signed-off-by: Andy Gross <andy.gross@linaro.org>
* drivers: qcom: rpmh-rsc: fix the loop index check in get_req_from_tcsRaju P.L.S.S.S.N2018-07-211-1/+1
| | | | | | | | | | | get_req_from_tcs introduced in patch[1] returns tcs_request from tcs_group. The size of tcs (of type - tcs_group) array in rsc_drv is TCS_TYPE_NR. So the loop index needs to be iterated up to TCS_TYPE_NR only. [1] https://patchwork.kernel.org/patch/10477547/ Signed-off-by: Raju P.L.S.S.S.N <rplsssn@codeaurora.org> Signed-off-by: Andy Gross <andy.gross@linaro.org>
* drivers: qcom: rpmh-rsc: Check cmd_db_ready() to help childrenDouglas Anderson2018-07-211-0/+13
| | | | | | | | | | | | | | | | | | Children of RPMh will need access to cmd_db. Rather than having each child have code to check if cmd_db is ready let's add the check to RPMh. With this we'll be able to remove this boilerplate code from clk-rpmh.c and qcom-rpmh-regulator.c. Neither of these files has landed upstream yet but patches are pretty far along. === This code is based upon v11 of Lina and Raju's RPMh series. Suggested-by: Stephen Boyd <sboyd@kernel.org> Signed-off-by: Douglas Anderson <dianders@chromium.org> Acked-by: Lina Iyer <ilina@codeaurora.org> Signed-off-by: Andy Gross <andy.gross@linaro.org>
* drivers: qcom: rpmh-rsc: allow active requests from wake TCSLina Iyer2018-07-211-2/+21
| | | | | | | | | | | | | | | | Some RSCs may only have sleep and wake TCS, i.e, there is no dedicated TCS for active mode request, but drivers may still want to make active requests from these RSCs. In such cases re-purpose the wake TCS to send active state requests. The requirement for this is that the driver is aware that the wake TCS is being repurposed to send active request, hence the sleep and wake TCSes be invalidated before the active request is sent. Signed-off-by: Lina Iyer <ilina@codeaurora.org> Signed-off-by: Raju P.L.S.S.S.N <rplsssn@codeaurora.org> Reviewed-by: Matthias Kaehlcke <mka@chromium.org> Signed-off-by: Andy Gross <andy.gross@linaro.org>
* drivers: qcom: rpmh: add support for batch RPMH requestLina Iyer2018-07-211-0/+1
| | | | | | | | | | | | | | | | | | Platform drivers need make a lot of resource state requests at the same time, say, at the start or end of an usecase. It can be quite inefficient to send each request separately. Instead they can give the RPMH library a batch of requests to be sent and wait on the whole transaction to be complete. rpmh_write_batch() is a blocking call that can be used to send multiple RPMH command sets. Each RPMH command set is set asynchronously and the API blocks until all the command sets are complete and receive their tx_done callbacks. Signed-off-by: Lina Iyer <ilina@codeaurora.org> Signed-off-by: Raju P.L.S.S.S.N <rplsssn@codeaurora.org> Reviewed-by: Matthias Kaehlcke <mka@chromium.org> Signed-off-by: Andy Gross <andy.gross@linaro.org>
* drivers: qcom: rpmh: cache sleep/wake state requestsLina Iyer2018-07-211-0/+3
| | | | | | | | | | | | | | | | | | | | | Active state requests are sent immediately to the RSC controller, while sleep and wake state requests are cached in this driver to avoid taxing the RSC controller repeatedly. The cached values will be sent to the controller when the rpmh_flush() is called. Generally, flushing is a system PM activity and may be called from the system PM drivers when the system is entering suspend or deeper sleep modes during cpuidle. Also allow invalidating the cached requests, so they may be re-populated again. Signed-off-by: Lina Iyer <ilina@codeaurora.org> [rplsssn: remove unneeded semicolon, address line over 80chars error] Signed-off-by: Raju P.L.S.S.S.N <rplsssn@codeaurora.org> Reviewed-by: Evan Green <evgreen@chromium.org> Reviewed-by: Matthias Kaehlcke <mka@chromium.org> Signed-off-by: Andy Gross <andy.gross@linaro.org>
* drivers: qcom: rpmh-rsc: allow invalidation of sleep/wake TCSLina Iyer2018-07-211-0/+44
| | | | | | | | | Allow sleep and wake commands to be cleared from the respective TCSes, so that they can be re-populated. Signed-off-by: Lina Iyer <ilina@codeaurora.org> Signed-off-by: Raju P.L.S.S.S.N <rplsssn@codeaurora.org> Signed-off-by: Andy Gross <andy.gross@linaro.org>
* drivers: qcom: rpmh-rsc: write sleep/wake requests to TCSLina Iyer2018-07-211-0/+121
| | | | | | | | | | | | | | | | | | | | Sleep and wake requests are sent when the application processor subsystem of the SoC is entering deep sleep states like in suspend. These requests help lower the system power requirements when the resources are not in use. Sleep and wake requests are written to the TCS slots but are not triggered at the time of writing. The TCS are triggered by the firmware after the last of the CPUs has executed its WFI. Since these requests may come in different batches of requests, it is the job of this controller driver to find and arrange the requests into the available TCSes. Signed-off-by: Lina Iyer <ilina@codeaurora.org> Signed-off-by: Raju P.L.S.S.S.N <rplsssn@codeaurora.org> Reviewed-by: Evan Green <evgreen@chromium.org> Reviewed-by: Matthias Kaehlcke <mka@chromium.org> Signed-off-by: Andy Gross <andy.gross@linaro.org>
* drivers: qcom: rpmh: add RPMH helper functionsLina Iyer2018-07-211-1/+5
| | | | | | | | | | | | | | Sending RPMH requests and waiting for response from the controller through a callback is common functionality across all platform drivers. To simplify drivers, add a library functions to create RPMH client and send resource state requests. rpmh_write() is a synchronous blocking call that can be used to send active state requests. Signed-off-by: Lina Iyer <ilina@codeaurora.org> Signed-off-by: Raju P.L.S.S.S.N <rplsssn@codeaurora.org> Signed-off-by: Andy Gross <andy.gross@linaro.org>
* drivers: qcom: rpmh-rsc: log RPMH requests in FTRACELina Iyer2018-07-211-1/+10
| | | | | | | | | | Log sent RPMH requests and interrupt responses in FTRACE. Signed-off-by: Lina Iyer <ilina@codeaurora.org> Reviewed-by: Steven Rostedt (VMware) <rostedt@goodmis.org> [rplsssn@codeaurora.org: rebase to v4.18-rc1 & fix merge conflict] Signed-off-by: Raju P.L.S.S.S.N <rplsssn@codeaurora.org> Signed-off-by: Andy Gross <andy.gross@linaro.org>
* drivers: qcom: rpmh-rsc: add RPMH controller for QCOM SoCsLina Iyer2018-07-211-0/+481
Add controller driver for QCOM SoCs that have hardware based shared resource management. The hardware IP known as RSC (Resource State Coordinator) houses multiple Direct Resource Voter (DRV) for different execution levels. A DRV is a unique voter on the state of a shared resource. A Trigger Control Set (TCS) is a bunch of slots that can house multiple resource state requests, that when triggered will issue those requests through an internal bus to the Resource Power Manager Hardened (RPMH) blocks. These hardware blocks are capable of adjusting clocks, voltages, etc. The resource state request from a DRV are aggregated along with state requests from other processors in the SoC and the aggregate value is applied on the resource. Some important aspects of the RPMH communication - - Requests are <addr, value> with some header information - Multiple requests (upto 16) may be sent through a TCS, at a time - Requests in a TCS are sent in sequence - Requests may be fire-n-forget or completion (response expected) - Multiple TCS from the same DRV may be triggered simultaneously - Cannot send a request if another request for the same addr is in progress from the same DRV - When all the requests from a TCS are complete, an IRQ is raised - The IRQ handler needs to clear the TCS before it is available for reuse - TCS configuration is specific to a DRV - Platform drivers may use DRV from different RSCs to make requests Resource state requests made when CPUs are active are called 'active' state requests. Requests made when all the CPUs are powered down (idle state) are called 'sleep' state requests. They are matched by a corresponding 'wake' state requests which puts the resources back in to previously requested active state before resuming any CPU. TCSes are dedicated for each type of requests. Active mode TCSes (AMC) are used to send requests immediately to the resource, while control TCS are used to provide specific information to the controller. Sleep and Wake TCS send sleep and wake requests, after and before the system halt respectively. Signed-off-by: Lina Iyer <ilina@codeaurora.org> Signed-off-by: Raju P.L.S.S.S.N <rplsssn@codeaurora.org> Signed-off-by: Andy Gross <andy.gross@linaro.org>