From patchwork Fri Nov 24 15:18:45 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Marangi X-Patchwork-Id: 13467781 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="atYfbph+" Received: from mail-wr1-x430.google.com (mail-wr1-x430.google.com [IPv6:2a00:1450:4864:20::430]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4E844171D; Fri, 24 Nov 2023 07:18:59 -0800 (PST) Received: by mail-wr1-x430.google.com with SMTP id ffacd0b85a97d-3316c6e299eso1335675f8f.1; Fri, 24 Nov 2023 07:18:59 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1700839138; x=1701443938; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=oVZXsVyggnQQBeZou9kqJ/xLa3R34SntugSTM7Apkww=; b=atYfbph+gm3gERpa+4mV9KvgZJaSQ2RRGJE3629QYgCiAJ7SK41fWM/BeMvyeEBH6U nt+gDC+1rvkQhrMQcuLl5QEIi2gGXE13+XSXJiEgFCUXJu3/uYlkPss6Ip77/RBEkY3V +R7wRTsINppd2PgUXbokoWEJlG+KmyjIWaYrVyHKUu22qkTD27SkgkaKRZQMgt8OO+ys t6bassJ7PawJNxkfivxQfRKSuPMNX3hg2kSKRXMMRAW4R1YucFEL4jTUp4CxlXcnuWSq yucmQ537s2OTWf1EzawoxJvi3UBo0Sbz24NPz6x0fn3lUR8tVuxSh7RiMQO9O5unKFeN tsBg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1700839138; x=1701443938; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=oVZXsVyggnQQBeZou9kqJ/xLa3R34SntugSTM7Apkww=; b=Al/FfzPywMKITaVxfjnd75VaWhO6e+qkhiqU7JnSmtpcHipuFIGP4520gwT0dDgzzW 9Nv2K/sgW7ZwndkwHluEwXll0KDkUAeV8N45h1kS8yDZ0792JmapLijx77BXtNB1iSMz xxZf5NhlbXtOCJvELkBcIw4opQqzbdlNP/m8HxSV01BbdWxu6Jd2NytRIICIpqKHrZzh RwufoPfzd7NajqmsByZrpAyXDtuMEO6mEWbd3jPWSALfTQ39x5MQghcM0N8gubKxUjt8 WeeYBgNzRuGQ3UVgsnahERewMszx/MYwh83F/e9/VYn/KRtXzM4YqmOe/jbV7y+kWA3R XerA== X-Gm-Message-State: AOJu0YzZC75SI52B9ihg9/qKg15cXjW2eravwxaMC2aKyzvRDIoY/kfL F5cDu0gQpSvhFmCLN9kXaF8= X-Google-Smtp-Source: AGHT+IEfFoMOk/AAm4HKDjSM09wxomJAmCiy8eFqTw5kSVLp81Bj3hoLeWWuxaoMSltXvRxKDWFvyQ== X-Received: by 2002:a5d:54c3:0:b0:32f:7c27:423b with SMTP id x3-20020a5d54c3000000b0032f7c27423bmr2551373wrv.51.1700839137449; Fri, 24 Nov 2023 07:18:57 -0800 (PST) Received: from localhost.localdomain ([78.209.42.235]) by smtp.googlemail.com with ESMTPSA id x12-20020adff64c000000b0032dcb08bf94sm4513699wrp.60.2023.11.24.07.18.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 24 Nov 2023 07:18:57 -0800 (PST) From: Christian Marangi To: Bjorn Andersson , Andy Gross , Konrad Dybcio , Michael Turquette , Stephen Boyd , linux-arm-msm@vger.kernel.org, linux-clk@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Christian Marangi Subject: [PATCH v7 1/3] clk: qcom: clk-rcg: introduce support for multiple conf for same freq Date: Fri, 24 Nov 2023 16:18:45 +0100 Message-Id: <20231124151847.1915-2-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20231124151847.1915-1-ansuelsmth@gmail.com> References: <20231124151847.1915-1-ansuelsmth@gmail.com> Precedence: bulk X-Mailing-List: linux-clk@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Some RCG frequency can be reached by multiple configuration. We currently declare multiple configuration for the same frequency but that is not supported and always the first configuration will be taken. These multiple configuration are needed as based on the current parent configuration, it may be needed to use a different configuration to reach the same frequency. To handle this introduce 3 new macro, C, FM and FMS: - C is used to declare a freq_conf where src, pre_div, m and n are provided. - FM is used to declare a freq_multi_tbl with the frequency and an array of confs to insert all the config for the provided frequency. - FMS is used to declare a freq_multi_tbl with the frequency and an array of a single conf with the provided src, pre_div, m and n. Struct clk_rcg2 is changed to add a union type to reference a simple freq_tbl or a complex freq_multi_tbl. Signed-off-by: Christian Marangi --- drivers/clk/qcom/clk-rcg.h | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/drivers/clk/qcom/clk-rcg.h b/drivers/clk/qcom/clk-rcg.h index e6d84c8c7989..c81458db6ce4 100644 --- a/drivers/clk/qcom/clk-rcg.h +++ b/drivers/clk/qcom/clk-rcg.h @@ -17,6 +17,23 @@ struct freq_tbl { u16 n; }; +#define C(s, h, m, n) { (s), (2 * (h) - 1), (m), (n) } +#define FM(f, confs) { (f), ARRAY_SIZE(confs), (confs) } +#define FMS(f, s, h, m, n) { (f), 1, (const struct freq_conf []){ C(s, h, m, n) } } + +struct freq_conf { + u8 src; + u8 pre_div; + u16 m; + u16 n; +}; + +struct freq_multi_tbl { + unsigned long freq; + int num_confs; + const struct freq_conf *confs; +}; + /** * struct mn - M/N:D counter * @mnctr_en_bit: bit to enable mn counter @@ -138,6 +155,7 @@ extern const struct clk_ops clk_dyn_rcg_ops; * @safe_src_index: safe src index value * @parent_map: map from software's parent index to hardware's src_sel field * @freq_tbl: frequency table + * @freq_multi_tbl: frequency table for clocks reachable with multiple RCGs conf * @clkr: regmap clock handle * @cfg_off: defines the cfg register offset from the CMD_RCGR + CFG_REG * @parked_cfg: cached value of the CFG register for parked RCGs @@ -149,7 +167,10 @@ struct clk_rcg2 { u8 hid_width; u8 safe_src_index; const struct parent_map *parent_map; - const struct freq_tbl *freq_tbl; + union { + const struct freq_tbl *freq_tbl; + const struct freq_multi_tbl *freq_multi_tbl; + }; struct clk_regmap clkr; u8 cfg_off; u32 parked_cfg; From patchwork Fri Nov 24 15:18:46 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Marangi X-Patchwork-Id: 13467782 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Lrd1aKsl" Received: from mail-wr1-x434.google.com (mail-wr1-x434.google.com [IPv6:2a00:1450:4864:20::434]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 659D41727; Fri, 24 Nov 2023 07:19:00 -0800 (PST) Received: by mail-wr1-x434.google.com with SMTP id ffacd0b85a97d-332c0c32d19so1329739f8f.3; Fri, 24 Nov 2023 07:19:00 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1700839139; x=1701443939; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=XqGZhUVvjUoM/m8Ls3VWD3DYZah9Vng+Z0rGhN0LtgQ=; b=Lrd1aKslTD+T+CXnhGZNxyeHxmG72GUCw8ZgNMZ8wRDgYRCfacvWNaWnWZm5uYqvSg EynVg395lyGUT/UerGziW3RhQHRFqV0M5Q9W2bKxExb6soDe0blYHw1BcElgZbvh2jht Lhc2sE2rSmTuV4vi8CaGKEu0YDrBbaDTaaUVyQR29teOKQ7MfJgq7fqF4+jwA3ed0881 jveO1GxGC2RG+gS0kr9q6Ld5rxRv0V2pkF23u6xinP8w9fPOvRfG+873ojvzwxQnyMqx UCmF/IUr/E7MThREKxTTJODysnSrcrYluv6loQdTqHGb8En1JE1f3qYVVdhbi77ERBxp H7vw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1700839139; x=1701443939; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=XqGZhUVvjUoM/m8Ls3VWD3DYZah9Vng+Z0rGhN0LtgQ=; b=HSUbYOthnytc4oxpLX+P0oplr1z48lzCBhB/uX2dwXfJCNG8LFbw3KGY2BD+Vkcgkl mcs50+4ohlhbtkjXn0ONyokTCEeanFF6OM9Kl3S0uJl1p4YJTHGFbJKtHbvZh61bG7Dt 2EwCWMiX5tanYhLMDVyVLBy81Ug0sFD6pYYWBrDdSjhm/m/j8ixTtPThtEY3tsSd3mBN Q/zg8GwA3PzAApVygFn36Xf89/HTxkbTEAaaCGv/J2wkJHnkBDzqkKcqra1IYe1LXbb9 G8Ytdoc8rYMC1vF/01cbHOvUJwbYcPdOdZTQqIrtFPoSiLLeRJQBVEcZTIdTjORjUE22 IUtg== X-Gm-Message-State: AOJu0YwM0NFrXtobBN3BV7CT0pk0z+fdRdFGEebCRT+thcdb9064D4Zi OJ2w1ZiHK+FmtiBn7ehT87Y= X-Google-Smtp-Source: AGHT+IHeSbwB5HeCG7s/D0mUEKP8bjIH6PhdsN3K2+X7KmNUGgyhhdmV11oCJvqdjop7JSqMp9ZG2Q== X-Received: by 2002:a5d:5551:0:b0:332:eaa7:56b0 with SMTP id g17-20020a5d5551000000b00332eaa756b0mr2051284wrw.14.1700839138787; Fri, 24 Nov 2023 07:18:58 -0800 (PST) Received: from localhost.localdomain ([78.209.42.235]) by smtp.googlemail.com with ESMTPSA id x12-20020adff64c000000b0032dcb08bf94sm4513699wrp.60.2023.11.24.07.18.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 24 Nov 2023 07:18:58 -0800 (PST) From: Christian Marangi To: Bjorn Andersson , Andy Gross , Konrad Dybcio , Michael Turquette , Stephen Boyd , linux-arm-msm@vger.kernel.org, linux-clk@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Christian Marangi Subject: [PATCH v7 2/3] clk: qcom: clk-rcg2: add support for rcg2 freq multi ops Date: Fri, 24 Nov 2023 16:18:46 +0100 Message-Id: <20231124151847.1915-3-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20231124151847.1915-1-ansuelsmth@gmail.com> References: <20231124151847.1915-1-ansuelsmth@gmail.com> Precedence: bulk X-Mailing-List: linux-clk@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Some RCG frequency can be reached by multiple configuration. Add clk_rcg2_fm_ops ops to support these special RCG configurations. These alternative ops will select the frequency using a CEIL policy. When the correct frequency is found, the correct config is selected by calculating the final rate (by checking the defined parent and values in the config that is being checked) and deciding based on the one that is less different than the requested one. These check are skipped if there is just on config for the requested freq. qcom_find_freq_multi is added to search the freq with the new struct freq_multi_tbl. __clk_rcg2_select_conf is used to select the correct conf by simulating the final clock. If a conf can't be found due to parent not reachable, a WARN is printed and -EINVAL is returned. Signed-off-by: Christian Marangi Tested-by: Wei Lei --- drivers/clk/qcom/clk-rcg.h | 1 + drivers/clk/qcom/clk-rcg2.c | 166 ++++++++++++++++++++++++++++++++++++ drivers/clk/qcom/common.c | 18 ++++ drivers/clk/qcom/common.h | 2 + 4 files changed, 187 insertions(+) diff --git a/drivers/clk/qcom/clk-rcg.h b/drivers/clk/qcom/clk-rcg.h index c81458db6ce4..dc9a77965e68 100644 --- a/drivers/clk/qcom/clk-rcg.h +++ b/drivers/clk/qcom/clk-rcg.h @@ -190,6 +190,7 @@ struct clk_rcg2_gfx3d { extern const struct clk_ops clk_rcg2_ops; extern const struct clk_ops clk_rcg2_floor_ops; +extern const struct clk_ops clk_rcg2_fm_ops; extern const struct clk_ops clk_rcg2_mux_closest_ops; extern const struct clk_ops clk_edp_pixel_ops; extern const struct clk_ops clk_byte_ops; diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c index e22baf3a7112..2393c7df0402 100644 --- a/drivers/clk/qcom/clk-rcg2.c +++ b/drivers/clk/qcom/clk-rcg2.c @@ -266,6 +266,115 @@ static int _freq_tbl_determine_rate(struct clk_hw *hw, const struct freq_tbl *f, return 0; } +static const struct freq_conf * +__clk_rcg2_select_conf(struct clk_hw *hw, const struct freq_multi_tbl *f, + unsigned long req_rate) +{ + unsigned long rate_diff, best_rate_diff = ULONG_MAX; + const struct freq_conf *conf, *best_conf = NULL; + struct clk_rcg2 *rcg = to_clk_rcg2(hw); + const char *name = clk_hw_get_name(hw); + unsigned long parent_rate, rate; + struct clk_hw *p; + int index, i; + + /* Exit early if only one config is defined */ + if (f->num_confs == 1) { + best_conf = f->confs; + goto exit; + } + + /* Search in each provided config the one that is near the wanted rate */ + for (i = 0, conf = f->confs; i < f->num_confs; i++, conf++) { + index = qcom_find_src_index(hw, rcg->parent_map, conf->src); + if (index < 0) + continue; + + p = clk_hw_get_parent_by_index(hw, index); + if (!p) + continue; + + parent_rate = clk_hw_get_rate(p); + rate = calc_rate(parent_rate, conf->n, conf->m, conf->n, conf->pre_div); + + if (rate == req_rate) { + best_conf = conf; + goto exit; + } + + rate_diff = abs(req_rate - rate); + if (rate_diff < best_rate_diff) { + best_rate_diff = rate_diff; + best_conf = conf; + } + } + + /* + * Very unlikely. Warn if we couldn't find a correct config + * due to parent not found in every config. + */ + if (unlikely(!best_conf)) { + WARN(1, "%s: can't find a configuration for rate %lu.", + name, req_rate); + return ERR_PTR(-EINVAL); + } + +exit: + return best_conf; +} + +static int _freq_tbl_fm_determine_rate(struct clk_hw *hw, const struct freq_multi_tbl *f, + struct clk_rate_request *req) +{ + unsigned long clk_flags, rate = req->rate; + struct clk_rcg2 *rcg = to_clk_rcg2(hw); + const struct freq_conf *conf; + struct clk_hw *p; + int index; + + f = qcom_find_freq_multi(f, rate); + if (!f || !f->confs) + return -EINVAL; + + conf = __clk_rcg2_select_conf(hw, f, rate); + if (IS_ERR(conf)) + return PTR_ERR(conf); + index = qcom_find_src_index(hw, rcg->parent_map, conf->src); + if (index < 0) + return index; + + clk_flags = clk_hw_get_flags(hw); + p = clk_hw_get_parent_by_index(hw, index); + if (!p) + return -EINVAL; + + if (clk_flags & CLK_SET_RATE_PARENT) { + rate = f->freq; + if (conf->pre_div) { + if (!rate) + rate = req->rate; + rate /= 2; + rate *= conf->pre_div + 1; + } + + if (conf->n) { + u64 tmp = rate; + + tmp = tmp * conf->n; + do_div(tmp, conf->m); + rate = tmp; + } + } else { + rate = clk_hw_get_rate(p); + } + + req->best_parent_hw = p; + req->best_parent_rate = rate; + req->rate = f->freq; + + return 0; +} + static int clk_rcg2_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) { @@ -282,6 +391,14 @@ static int clk_rcg2_determine_floor_rate(struct clk_hw *hw, return _freq_tbl_determine_rate(hw, rcg->freq_tbl, req, FLOOR); } +static int clk_rcg2_fm_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) +{ + struct clk_rcg2 *rcg = to_clk_rcg2(hw); + + return _freq_tbl_fm_determine_rate(hw, rcg->freq_multi_tbl, req); +} + static int __clk_rcg2_configure(struct clk_rcg2 *rcg, const struct freq_tbl *f, u32 *_cfg) { @@ -377,6 +494,30 @@ static int __clk_rcg2_set_rate(struct clk_hw *hw, unsigned long rate, return clk_rcg2_configure(rcg, f); } +static int __clk_rcg2_fm_set_rate(struct clk_hw *hw, unsigned long rate) +{ + struct clk_rcg2 *rcg = to_clk_rcg2(hw); + const struct freq_multi_tbl *f; + const struct freq_conf *conf; + struct freq_tbl f_tbl; + + f = qcom_find_freq_multi(rcg->freq_multi_tbl, rate); + if (!f || !f->confs) + return -EINVAL; + + conf = __clk_rcg2_select_conf(hw, f, rate); + if (IS_ERR(conf)) + return PTR_ERR(conf); + + f_tbl.freq = f->freq; + f_tbl.src = conf->src; + f_tbl.pre_div = conf->pre_div; + f_tbl.m = conf->m; + f_tbl.n = conf->n; + + return clk_rcg2_configure(rcg, &f_tbl); +} + static int clk_rcg2_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) { @@ -389,6 +530,12 @@ static int clk_rcg2_set_floor_rate(struct clk_hw *hw, unsigned long rate, return __clk_rcg2_set_rate(hw, rate, FLOOR); } +static int clk_rcg2_fm_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + return __clk_rcg2_fm_set_rate(hw, rate); +} + static int clk_rcg2_set_rate_and_parent(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate, u8 index) { @@ -401,6 +548,12 @@ static int clk_rcg2_set_floor_rate_and_parent(struct clk_hw *hw, return __clk_rcg2_set_rate(hw, rate, FLOOR); } +static int clk_rcg2_fm_set_rate_and_parent(struct clk_hw *hw, + unsigned long rate, unsigned long parent_rate, u8 index) +{ + return __clk_rcg2_fm_set_rate(hw, rate); +} + static int clk_rcg2_get_duty_cycle(struct clk_hw *hw, struct clk_duty *duty) { struct clk_rcg2 *rcg = to_clk_rcg2(hw); @@ -511,6 +664,19 @@ const struct clk_ops clk_rcg2_floor_ops = { }; EXPORT_SYMBOL_GPL(clk_rcg2_floor_ops); +const struct clk_ops clk_rcg2_fm_ops = { + .is_enabled = clk_rcg2_is_enabled, + .get_parent = clk_rcg2_get_parent, + .set_parent = clk_rcg2_set_parent, + .recalc_rate = clk_rcg2_recalc_rate, + .determine_rate = clk_rcg2_fm_determine_rate, + .set_rate = clk_rcg2_fm_set_rate, + .set_rate_and_parent = clk_rcg2_fm_set_rate_and_parent, + .get_duty_cycle = clk_rcg2_get_duty_cycle, + .set_duty_cycle = clk_rcg2_set_duty_cycle, +}; +EXPORT_SYMBOL_GPL(clk_rcg2_fm_ops); + const struct clk_ops clk_rcg2_mux_closest_ops = { .determine_rate = __clk_mux_determine_rate_closest, .get_parent = clk_rcg2_get_parent, diff --git a/drivers/clk/qcom/common.c b/drivers/clk/qcom/common.c index 75f09e6e057e..48f81e3a5e80 100644 --- a/drivers/clk/qcom/common.c +++ b/drivers/clk/qcom/common.c @@ -41,6 +41,24 @@ struct freq_tbl *qcom_find_freq(const struct freq_tbl *f, unsigned long rate) } EXPORT_SYMBOL_GPL(qcom_find_freq); +const struct freq_multi_tbl *qcom_find_freq_multi(const struct freq_multi_tbl *f, + unsigned long rate) +{ + if (!f) + return NULL; + + if (!f->freq) + return f; + + for (; f->freq; f++) + if (rate <= f->freq) + return f; + + /* Default to our fastest rate */ + return f - 1; +} +EXPORT_SYMBOL_GPL(qcom_find_freq_multi); + const struct freq_tbl *qcom_find_freq_floor(const struct freq_tbl *f, unsigned long rate) { diff --git a/drivers/clk/qcom/common.h b/drivers/clk/qcom/common.h index 9c8f7b798d9f..2d4a8a837e6c 100644 --- a/drivers/clk/qcom/common.h +++ b/drivers/clk/qcom/common.h @@ -45,6 +45,8 @@ extern const struct freq_tbl *qcom_find_freq(const struct freq_tbl *f, unsigned long rate); extern const struct freq_tbl *qcom_find_freq_floor(const struct freq_tbl *f, unsigned long rate); +extern const struct freq_multi_tbl *qcom_find_freq_multi(const struct freq_multi_tbl *f, + unsigned long rate); extern void qcom_pll_set_fsm_mode(struct regmap *m, u32 reg, u8 bias_count, u8 lock_count); extern int qcom_find_src_index(struct clk_hw *hw, const struct parent_map *map, From patchwork Fri Nov 24 15:18:47 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Marangi X-Patchwork-Id: 13467783 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="bWC1zE/3" Received: from mail-wm1-x330.google.com (mail-wm1-x330.google.com [IPv6:2a00:1450:4864:20::330]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1DCB41723; Fri, 24 Nov 2023 07:19:02 -0800 (PST) Received: by mail-wm1-x330.google.com with SMTP id 5b1f17b1804b1-4079ed65582so13676505e9.1; Fri, 24 Nov 2023 07:19:02 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1700839140; x=1701443940; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=R0/dU+s24A21H8KB1oHsdy9DBO1Q1Csxfdq88eybO/s=; b=bWC1zE/3YuRVIpqeRoLz3sIoU0gkXLSPZt5/QZ6Rp5KDSXghKb8H03iEDiaBK5CG+0 ioxdjcSjOe61SKBKRklugQFCSCbsZIOSygw1TVfJlKNJu3vFO1U4/CoZTo/8dV/Y32Xb LVvdhAibulc7uORNB5qO0DYjjzjZigUYS/F5FOXeVuX5iyOyvWWb+cYQt628S3kVxW+n YeC9Uqpg4hO5CSwPVbsJ5wpVYp3UofuaMLJ6c2VI2KIGL1R0S+1TvoocJ9E9k/4CXJGC gkojoUlAvNmcB1ZIsm55vycpz5J728voIrm6JIltLFMFyO3fLH7GWkQtQm8GAJcnc8KW dHWQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1700839140; x=1701443940; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=R0/dU+s24A21H8KB1oHsdy9DBO1Q1Csxfdq88eybO/s=; b=cw+bV8I75Wa9nEs+J+zLY9FXta5Vy6wh5BWY6LAJGXVOEDFLXA4KDortIkA/jUA78/ LV40xAxZomMi7QwhgMa1WoKmjJUrIEQYdqa5xRe48DUDVogM/Mj/WcTxbjXzH4xLuPad 0JYA67PzE8qrP9IQSrNeW4dwQNW5nhhmQ25WTidIDebNb30+SL24+ss5OIe+8leK6/jw FL12mgyttmj+rW5lZkzRDx/WnP9eVTOMRM44kUtDAf6JiO8u89767oWlFt+Gyjs5SdrH EfQe3QOiDJ7X5C9Z/xNlDe7N230gCbCHIKa5vl1wFNDbWUksOlCieGo7CnP/1Afsb15G 3nAA== X-Gm-Message-State: AOJu0YwTiqgHarYdsOuxv+tH8OfU4iaq8y92gBYsckFZZugxHOoTQa+v ID0ltiXjNH8gkB4PdkD2ftk= X-Google-Smtp-Source: AGHT+IEE5YKz/4ooMFfdZ+RwQzm3azmhoIA7WYOU9MXK+PiJoogDpOwVolUwITxe91fc/pyNQB6Luw== X-Received: by 2002:a05:600c:4507:b0:40b:338b:5f10 with SMTP id t7-20020a05600c450700b0040b338b5f10mr2815122wmo.32.1700839140192; Fri, 24 Nov 2023 07:19:00 -0800 (PST) Received: from localhost.localdomain ([78.209.42.235]) by smtp.googlemail.com with ESMTPSA id x12-20020adff64c000000b0032dcb08bf94sm4513699wrp.60.2023.11.24.07.18.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 24 Nov 2023 07:18:59 -0800 (PST) From: Christian Marangi To: Bjorn Andersson , Andy Gross , Konrad Dybcio , Michael Turquette , Stephen Boyd , linux-arm-msm@vger.kernel.org, linux-clk@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Christian Marangi Subject: [PATCH v7 3/3] clk: qcom: gcc-ipq8074: rework nss_port5/6 clock to multiple conf Date: Fri, 24 Nov 2023 16:18:47 +0100 Message-Id: <20231124151847.1915-4-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20231124151847.1915-1-ansuelsmth@gmail.com> References: <20231124151847.1915-1-ansuelsmth@gmail.com> Precedence: bulk X-Mailing-List: linux-clk@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Rework nss_port5/6 to use the new multiple configuration implementation and correctly fix the clocks for these port under some corner case. This is particularly relevant for device that have 2.5G or 10G port connected to port5 or port 6 on ipq8074. As the parent are shared across multiple port it may be required to select the correct configuration to accomplish the desired clock. Without this patch such port doesn't work in some specific ethernet speed as the clock will be set to the wrong frequency as we just select the first configuration for the related frequency instead of selecting the best one. Signed-off-by: Christian Marangi --- drivers/clk/qcom/gcc-ipq8074.c | 120 +++++++++++++++++++++------------ 1 file changed, 76 insertions(+), 44 deletions(-) diff --git a/drivers/clk/qcom/gcc-ipq8074.c b/drivers/clk/qcom/gcc-ipq8074.c index 63ac2ced76bb..595cb7bd4834 100644 --- a/drivers/clk/qcom/gcc-ipq8074.c +++ b/drivers/clk/qcom/gcc-ipq8074.c @@ -1681,15 +1681,23 @@ static struct clk_regmap_div nss_port4_tx_div_clk_src = { }, }; -static const struct freq_tbl ftbl_nss_port5_rx_clk_src[] = { - F(19200000, P_XO, 1, 0, 0), - F(25000000, P_UNIPHY1_RX, 12.5, 0, 0), - F(25000000, P_UNIPHY0_RX, 5, 0, 0), - F(78125000, P_UNIPHY1_RX, 4, 0, 0), - F(125000000, P_UNIPHY1_RX, 2.5, 0, 0), - F(125000000, P_UNIPHY0_RX, 1, 0, 0), - F(156250000, P_UNIPHY1_RX, 2, 0, 0), - F(312500000, P_UNIPHY1_RX, 1, 0, 0), +static const struct freq_conf ftbl_nss_port5_rx_clk_src_25[] = { + C(P_UNIPHY1_RX, 12.5, 0, 0), + C(P_UNIPHY0_RX, 5, 0, 0), +}; + +static const struct freq_conf ftbl_nss_port5_rx_clk_src_125[] = { + C(P_UNIPHY1_RX, 2.5, 0, 0), + C(P_UNIPHY0_RX, 1, 0, 0), +}; + +static const struct freq_multi_tbl ftbl_nss_port5_rx_clk_src[] = { + FMS(19200000, P_XO, 1, 0, 0), + FM(25000000, ftbl_nss_port5_rx_clk_src_25), + FMS(78125000, P_UNIPHY1_RX, 4, 0, 0), + FM(125000000, ftbl_nss_port5_rx_clk_src_125), + FMS(156250000, P_UNIPHY1_RX, 2, 0, 0), + FMS(312500000, P_UNIPHY1_RX, 1, 0, 0), { } }; @@ -1716,14 +1724,14 @@ gcc_xo_uniphy0_rx_tx_uniphy1_rx_tx_ubi32_bias_map[] = { static struct clk_rcg2 nss_port5_rx_clk_src = { .cmd_rcgr = 0x68060, - .freq_tbl = ftbl_nss_port5_rx_clk_src, + .freq_multi_tbl = ftbl_nss_port5_rx_clk_src, .hid_width = 5, .parent_map = gcc_xo_uniphy0_rx_tx_uniphy1_rx_tx_ubi32_bias_map, .clkr.hw.init = &(struct clk_init_data){ .name = "nss_port5_rx_clk_src", .parent_data = gcc_xo_uniphy0_rx_tx_uniphy1_rx_tx_ubi32_bias, .num_parents = ARRAY_SIZE(gcc_xo_uniphy0_rx_tx_uniphy1_rx_tx_ubi32_bias), - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_fm_ops, }, }; @@ -1743,15 +1751,23 @@ static struct clk_regmap_div nss_port5_rx_div_clk_src = { }, }; -static const struct freq_tbl ftbl_nss_port5_tx_clk_src[] = { - F(19200000, P_XO, 1, 0, 0), - F(25000000, P_UNIPHY1_TX, 12.5, 0, 0), - F(25000000, P_UNIPHY0_TX, 5, 0, 0), - F(78125000, P_UNIPHY1_TX, 4, 0, 0), - F(125000000, P_UNIPHY1_TX, 2.5, 0, 0), - F(125000000, P_UNIPHY0_TX, 1, 0, 0), - F(156250000, P_UNIPHY1_TX, 2, 0, 0), - F(312500000, P_UNIPHY1_TX, 1, 0, 0), +static const struct freq_conf ftbl_nss_port5_tx_clk_src_25[] = { + C(P_UNIPHY1_TX, 12.5, 0, 0), + C(P_UNIPHY0_TX, 5, 0, 0), +}; + +static const struct freq_conf ftbl_nss_port5_tx_clk_src_125[] = { + C(P_UNIPHY1_TX, 2.5, 0, 0), + C(P_UNIPHY0_TX, 1, 0, 0), +}; + +static const struct freq_multi_tbl ftbl_nss_port5_tx_clk_src[] = { + FMS(19200000, P_XO, 1, 0, 0), + FM(25000000, ftbl_nss_port5_tx_clk_src_25), + FMS(78125000, P_UNIPHY1_TX, 4, 0, 0), + FM(125000000, ftbl_nss_port5_tx_clk_src_125), + FMS(156250000, P_UNIPHY1_TX, 2, 0, 0), + FMS(312500000, P_UNIPHY1_TX, 1, 0, 0), { } }; @@ -1778,14 +1794,14 @@ gcc_xo_uniphy0_tx_rx_uniphy1_tx_rx_ubi32_bias_map[] = { static struct clk_rcg2 nss_port5_tx_clk_src = { .cmd_rcgr = 0x68068, - .freq_tbl = ftbl_nss_port5_tx_clk_src, + .freq_multi_tbl = ftbl_nss_port5_tx_clk_src, .hid_width = 5, .parent_map = gcc_xo_uniphy0_tx_rx_uniphy1_tx_rx_ubi32_bias_map, .clkr.hw.init = &(struct clk_init_data){ .name = "nss_port5_tx_clk_src", .parent_data = gcc_xo_uniphy0_tx_rx_uniphy1_tx_rx_ubi32_bias, .num_parents = ARRAY_SIZE(gcc_xo_uniphy0_tx_rx_uniphy1_tx_rx_ubi32_bias), - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_fm_ops, }, }; @@ -1805,15 +1821,23 @@ static struct clk_regmap_div nss_port5_tx_div_clk_src = { }, }; -static const struct freq_tbl ftbl_nss_port6_rx_clk_src[] = { - F(19200000, P_XO, 1, 0, 0), - F(25000000, P_UNIPHY2_RX, 5, 0, 0), - F(25000000, P_UNIPHY2_RX, 12.5, 0, 0), - F(78125000, P_UNIPHY2_RX, 4, 0, 0), - F(125000000, P_UNIPHY2_RX, 1, 0, 0), - F(125000000, P_UNIPHY2_RX, 2.5, 0, 0), - F(156250000, P_UNIPHY2_RX, 2, 0, 0), - F(312500000, P_UNIPHY2_RX, 1, 0, 0), +static const struct freq_conf ftbl_nss_port6_rx_clk_src_25[] = { + C(P_UNIPHY2_RX, 5, 0, 0), + C(P_UNIPHY2_RX, 12.5, 0, 0), +}; + +static const struct freq_conf ftbl_nss_port6_rx_clk_src_125[] = { + C(P_UNIPHY2_RX, 1, 0, 0), + C(P_UNIPHY2_RX, 2.5, 0, 0), +}; + +static const struct freq_multi_tbl ftbl_nss_port6_rx_clk_src[] = { + FMS(19200000, P_XO, 1, 0, 0), + FM(25000000, ftbl_nss_port6_rx_clk_src_25), + FMS(78125000, P_UNIPHY2_RX, 4, 0, 0), + FM(125000000, ftbl_nss_port6_rx_clk_src_125), + FMS(156250000, P_UNIPHY2_RX, 2, 0, 0), + FMS(312500000, P_UNIPHY2_RX, 1, 0, 0), { } }; @@ -1835,14 +1859,14 @@ static const struct parent_map gcc_xo_uniphy2_rx_tx_ubi32_bias_map[] = { static struct clk_rcg2 nss_port6_rx_clk_src = { .cmd_rcgr = 0x68070, - .freq_tbl = ftbl_nss_port6_rx_clk_src, + .freq_multi_tbl = ftbl_nss_port6_rx_clk_src, .hid_width = 5, .parent_map = gcc_xo_uniphy2_rx_tx_ubi32_bias_map, .clkr.hw.init = &(struct clk_init_data){ .name = "nss_port6_rx_clk_src", .parent_data = gcc_xo_uniphy2_rx_tx_ubi32_bias, .num_parents = ARRAY_SIZE(gcc_xo_uniphy2_rx_tx_ubi32_bias), - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_fm_ops, }, }; @@ -1862,15 +1886,23 @@ static struct clk_regmap_div nss_port6_rx_div_clk_src = { }, }; -static const struct freq_tbl ftbl_nss_port6_tx_clk_src[] = { - F(19200000, P_XO, 1, 0, 0), - F(25000000, P_UNIPHY2_TX, 5, 0, 0), - F(25000000, P_UNIPHY2_TX, 12.5, 0, 0), - F(78125000, P_UNIPHY2_TX, 4, 0, 0), - F(125000000, P_UNIPHY2_TX, 1, 0, 0), - F(125000000, P_UNIPHY2_TX, 2.5, 0, 0), - F(156250000, P_UNIPHY2_TX, 2, 0, 0), - F(312500000, P_UNIPHY2_TX, 1, 0, 0), +static const struct freq_conf ftbl_nss_port6_tx_clk_src_25[] = { + C(P_UNIPHY2_TX, 5, 0, 0), + C(P_UNIPHY2_TX, 12.5, 0, 0), +}; + +static const struct freq_conf ftbl_nss_port6_tx_clk_src_125[] = { + C(P_UNIPHY2_TX, 1, 0, 0), + C(P_UNIPHY2_TX, 2.5, 0, 0), +}; + +static const struct freq_multi_tbl ftbl_nss_port6_tx_clk_src[] = { + FMS(19200000, P_XO, 1, 0, 0), + FM(25000000, ftbl_nss_port6_tx_clk_src_25), + FMS(78125000, P_UNIPHY1_RX, 4, 0, 0), + FM(125000000, ftbl_nss_port6_tx_clk_src_125), + FMS(156250000, P_UNIPHY1_RX, 2, 0, 0), + FMS(312500000, P_UNIPHY1_RX, 1, 0, 0), { } }; @@ -1892,14 +1924,14 @@ static const struct parent_map gcc_xo_uniphy2_tx_rx_ubi32_bias_map[] = { static struct clk_rcg2 nss_port6_tx_clk_src = { .cmd_rcgr = 0x68078, - .freq_tbl = ftbl_nss_port6_tx_clk_src, + .freq_multi_tbl = ftbl_nss_port6_tx_clk_src, .hid_width = 5, .parent_map = gcc_xo_uniphy2_tx_rx_ubi32_bias_map, .clkr.hw.init = &(struct clk_init_data){ .name = "nss_port6_tx_clk_src", .parent_data = gcc_xo_uniphy2_tx_rx_ubi32_bias, .num_parents = ARRAY_SIZE(gcc_xo_uniphy2_tx_rx_ubi32_bias), - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_fm_ops, }, };