Commit 956deab5 authored by Krzysztof Kozlowski's avatar Krzysztof Kozlowski Committed by Bjorn Andersson

soc: qcom: icc-bwmon: clear all registers on init

The hardware programming guide recommends to clear all registers on
first initialization, through separate field in BWMON_CLEAR register.

This makes sense in general but especially if driver is rebound to avoid
spurious/early interrupts.

Cc: Rajendra Nayak <quic_rjendra@quicinc.com>
Cc: Sibi Sankar <quic_sibis@quicinc.com>
Signed-off-by: default avatarKrzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Tested-by: default avatarSteev Klimaszewski <steev@kali.org>
Signed-off-by: default avatarBjorn Andersson <bjorn.andersson@linaro.org>
Link: https://lore.kernel.org/r/20220728113748.170548-6-krzysztof.kozlowski@linaro.org
parent 1dd5246e
...@@ -50,6 +50,7 @@ ...@@ -50,6 +50,7 @@
#define BWMON_CLEAR 0x2a4 #define BWMON_CLEAR 0x2a4
#define BWMON_CLEAR_CLEAR BIT(0) #define BWMON_CLEAR_CLEAR BIT(0)
#define BWMON_CLEAR_CLEAR_ALL BIT(1)
#define BWMON_SAMPLE_WINDOW 0x2a8 #define BWMON_SAMPLE_WINDOW 0x2a8
#define BWMON_THRESHOLD_HIGH 0x2ac #define BWMON_THRESHOLD_HIGH 0x2ac
...@@ -127,8 +128,12 @@ struct icc_bwmon { ...@@ -127,8 +128,12 @@ struct icc_bwmon {
unsigned int current_kbps; unsigned int current_kbps;
}; };
static void bwmon_clear_counters(struct icc_bwmon *bwmon) static void bwmon_clear_counters(struct icc_bwmon *bwmon, bool clear_all)
{ {
unsigned int val = BWMON_CLEAR_CLEAR;
if (clear_all)
val |= BWMON_CLEAR_CLEAR_ALL;
/* /*
* Clear counters. The order and barriers are * Clear counters. The order and barriers are
* important. Quoting downstream Qualcomm msm-4.9 tree: * important. Quoting downstream Qualcomm msm-4.9 tree:
...@@ -137,7 +142,7 @@ static void bwmon_clear_counters(struct icc_bwmon *bwmon) ...@@ -137,7 +142,7 @@ static void bwmon_clear_counters(struct icc_bwmon *bwmon)
* region. So, we need to make sure the counter clear is completed * region. So, we need to make sure the counter clear is completed
* before we try to clear the IRQ or do any other counter operations. * before we try to clear the IRQ or do any other counter operations.
*/ */
writel(BWMON_CLEAR_CLEAR, bwmon->base + BWMON_CLEAR); writel(val, bwmon->base + BWMON_CLEAR);
} }
static void bwmon_clear_irq(struct icc_bwmon *bwmon) static void bwmon_clear_irq(struct icc_bwmon *bwmon)
...@@ -208,7 +213,7 @@ static void bwmon_start(struct icc_bwmon *bwmon) ...@@ -208,7 +213,7 @@ static void bwmon_start(struct icc_bwmon *bwmon)
unsigned int thres_count; unsigned int thres_count;
int window; int window;
bwmon_clear_counters(bwmon); bwmon_clear_counters(bwmon, true);
window = mult_frac(bwmon->data->sample_ms, HW_TIMER_HZ, MSEC_PER_SEC); window = mult_frac(bwmon->data->sample_ms, HW_TIMER_HZ, MSEC_PER_SEC);
/* Maximum sampling window: 0xfffff */ /* Maximum sampling window: 0xfffff */
...@@ -304,7 +309,7 @@ static irqreturn_t bwmon_intr_thread(int irq, void *dev_id) ...@@ -304,7 +309,7 @@ static irqreturn_t bwmon_intr_thread(int irq, void *dev_id)
bwmon_set_threshold(bwmon, BWMON_THRESHOLD_HIGH, up_kbps); bwmon_set_threshold(bwmon, BWMON_THRESHOLD_HIGH, up_kbps);
bwmon_set_threshold(bwmon, BWMON_THRESHOLD_MED, down_kbps); bwmon_set_threshold(bwmon, BWMON_THRESHOLD_MED, down_kbps);
/* Write barriers in bwmon_clear_counters() */ /* Write barriers in bwmon_clear_counters() */
bwmon_clear_counters(bwmon); bwmon_clear_counters(bwmon, false);
bwmon_clear_irq(bwmon); bwmon_clear_irq(bwmon);
bwmon_enable(bwmon, irq_enable); bwmon_enable(bwmon, irq_enable);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment