From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753900AbcIAJfQ (ORCPT ); Thu, 1 Sep 2016 05:35:16 -0400 Received: from gloria.sntech.de ([95.129.55.99]:56629 "EHLO gloria.sntech.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750895AbcIAJfI (ORCPT ); Thu, 1 Sep 2016 05:35:08 -0400 From: Heiko =?ISO-8859-1?Q?St=FCbner?= To: Lin Huang Cc: myungjoo.ham@samsung.com, tixy@linaro.org, mark.rutland@arm.com, typ@rock-chips.com, linux-rockchip@lists.infradead.org, airlied@linux.ie, mturquette@baylibre.com, dbasehore@chromium.org, sboyd@codeaurora.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, dianders@chromium.org, cw00.choi@samsung.com, kyungmin.park@samsung.com, sudeep.holla@arm.com, linux-pm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, mark.yao@rock-chips.com Subject: Re: [PATCH v7 1/8] clk: rockchip: add new clock-type for the ddrclk Date: Thu, 01 Sep 2016 11:34:50 +0200 Message-ID: <2457390.MqltFPe7p9@diego> User-Agent: KMail/4.14.10 (Linux/4.6.0-1-amd64; KDE/4.14.22; x86_64; ; ) In-Reply-To: <1471836984-6316-2-git-send-email-hl@rock-chips.com> References: <1471836984-6316-1-git-send-email-hl@rock-chips.com> <1471836984-6316-2-git-send-email-hl@rock-chips.com> MIME-Version: 1.0 Content-Transfer-Encoding: 7Bit Content-Type: text/plain; charset="us-ascii" Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Am Montag, 22. August 2016, 11:36:17 schrieb Lin Huang: > On new rockchip platform(rk3399 etc), there have dcf controller to > do ddr frequency scaling, and this controller will implement in > arm-trust-firmware. We add a special clock-type to handle that. > > Signed-off-by: Lin Huang Applied with some changes: - split the sip header into a separate patch [0], as we'll need the devfreq part to also have access to that - reword the commit message [1] to have some more details on what we want to accomplish here - drop the NO_CACHE flag as per our chat, as we now also have the round-rate talking to the ATF, so the cached value should actuall match [0] https://git.kernel.org/cgit/linux/kernel/git/mmind/linux-rockchip.git/commit/?id=97dd82682f1a6174698fbea149a04b4cabc58c4f [1] https://git.kernel.org/cgit/linux/kernel/git/mmind/linux-rockchip.git/commit/?id=a4f182bf81f18f91f1aef6289fcdfa6a2ac51b99 > --- > Changes in v7: > - add rockchip_ddrclk_sip_ops so we can distinguish other ddr clock operate > - add ROCKCHIP_SIP_CONFIG_* in rockchip_sip.h give constants a specific name > > Changes in v6: > - none > > Changes in v5: > - delete unuse mux_flag > - use div_flag to distinguish sip call and other operate > > Changes in v4: > - use arm_smccc_smc() to set/read ddr rate > > Changes in v3: > - use sip call to set/read ddr rate > > Changes in v2: > - use GENMASK instead val_mask > - use divider_recalc_rate() instead DIV_ROUND_UP_ULL > - cleanup code > > Changes in v1: > - none > > drivers/clk/rockchip/Makefile | 1 + > drivers/clk/rockchip/clk-ddr.c | 157 > ++++++++++++++++++++++++++++++++++++ drivers/clk/rockchip/clk.c | > 9 +++ > drivers/clk/rockchip/clk.h | 35 ++++++++ > include/soc/rockchip/rockchip_sip.h | 27 +++++++ > 5 files changed, 229 insertions(+) > create mode 100644 drivers/clk/rockchip/clk-ddr.c > create mode 100644 include/soc/rockchip/rockchip_sip.h > > diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile > index f47a2fa..b5f2c8e 100644 > --- a/drivers/clk/rockchip/Makefile > +++ b/drivers/clk/rockchip/Makefile > @@ -8,6 +8,7 @@ obj-y += clk-pll.o > obj-y += clk-cpu.o > obj-y += clk-inverter.o > obj-y += clk-mmc-phase.o > +obj-y += clk-ddr.o > obj-$(CONFIG_RESET_CONTROLLER) += softrst.o > > obj-y += clk-rk3036.o > diff --git a/drivers/clk/rockchip/clk-ddr.c b/drivers/clk/rockchip/clk-ddr.c > new file mode 100644 > index 0000000..224e07e > --- /dev/null > +++ b/drivers/clk/rockchip/clk-ddr.c > @@ -0,0 +1,157 @@ > +/* > + * Copyright (c) 2016 Rockchip Electronics Co. Ltd. > + * Author: Lin Huang > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License as published by > + * the Free Software Foundation; either version 2 of the License, or > + * (at your option) any later version. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include "clk.h" > + > +struct rockchip_ddrclk { > + struct clk_hw hw; > + void __iomem *reg_base; > + int mux_offset; > + int mux_shift; > + int mux_width; > + int div_shift; > + int div_width; > + int ddr_flag; > + spinlock_t *lock; > +}; > + > +#define to_rockchip_ddrclk_hw(hw) container_of(hw, struct rockchip_ddrclk, > hw) + > +static int rockchip_ddrclk_sip_set_rate(struct clk_hw *hw, unsigned long > drate, + unsigned long prate) > +{ > + struct rockchip_ddrclk *ddrclk = to_rockchip_ddrclk_hw(hw); > + unsigned long flags; > + struct arm_smccc_res res; > + > + spin_lock_irqsave(ddrclk->lock, flags); > + arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, drate, 0, > + ROCKCHIP_SIP_CONFIG_DRAM_SET_RATE, > + 0, 0, 0, 0, &res); > + spin_unlock_irqrestore(ddrclk->lock, flags); > + > + return res.a0; > +} > + > +static unsigned long > +rockchip_ddrclk_sip_recalc_rate(struct clk_hw *hw, > + unsigned long parent_rate) > +{ > + struct arm_smccc_res res; > + > + arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, 0, 0, > + ROCKCHIP_SIP_CONFIG_DRAM_GET_RATE, > + 0, 0, 0, 0, &res); > + > + return res.a0; > +} > + > +static long rockchip_ddrclk_sip_round_rate(struct clk_hw *hw, > + unsigned long rate, > + unsigned long *prate) > +{ > + struct arm_smccc_res res; > + > + arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, rate, 0, > + ROCKCHIP_SIP_CONFIG_DRAM_ROUND_RATE, > + 0, 0, 0, 0, &res); > + > + return res.a0; > +} > + > +static u8 rockchip_ddrclk_get_parent(struct clk_hw *hw) > +{ > + struct rockchip_ddrclk *ddrclk = to_rockchip_ddrclk_hw(hw); > + int num_parents = clk_hw_get_num_parents(hw); > + u32 val; > + > + val = clk_readl(ddrclk->reg_base + > + ddrclk->mux_offset) >> ddrclk->mux_shift; > + val &= GENMASK(ddrclk->mux_width - 1, 0); > + > + if (val >= num_parents) > + return -EINVAL; > + > + return val; > +} > + > +static const struct clk_ops rockchip_ddrclk_sip_ops = { > + .recalc_rate = rockchip_ddrclk_sip_recalc_rate, > + .set_rate = rockchip_ddrclk_sip_set_rate, > + .round_rate = rockchip_ddrclk_sip_round_rate, > + .get_parent = rockchip_ddrclk_get_parent, > +}; > + > +struct clk *rockchip_clk_register_ddrclk(const char *name, int flags, > + const char *const *parent_names, > + u8 num_parents, int mux_offset, > + int mux_shift, int mux_width, > + int div_shift, int div_width, > + int ddr_flag, void __iomem *reg_base, > + spinlock_t *lock) > +{ > + struct rockchip_ddrclk *ddrclk; > + struct clk_init_data init; > + struct clk *clk; > + > + ddrclk = kzalloc(sizeof(*ddrclk), GFP_KERNEL); > + if (!ddrclk) > + return ERR_PTR(-ENOMEM); > + > + init.name = name; > + init.parent_names = parent_names; > + init.num_parents = num_parents; > + > + init.flags = flags; > + init.flags |= CLK_SET_RATE_NO_REPARENT; > + init.flags |= CLK_GET_RATE_NOCACHE; > + > + switch (ddr_flag) { > + case ROCKCHIP_DDRCLK_SIP: > + init.ops = &rockchip_ddrclk_sip_ops; > + break; > + default: > + pr_err("%s: unsupported ddrclk type %d\n", __func__, ddr_flag); > + kfree(ddrclk); > + return ERR_PTR(-EINVAL); > + } > + > + ddrclk->reg_base = reg_base; > + ddrclk->lock = lock; > + ddrclk->hw.init = &init; > + ddrclk->mux_offset = mux_offset; > + ddrclk->mux_shift = mux_shift; > + ddrclk->mux_width = mux_width; > + ddrclk->div_shift = div_shift; > + ddrclk->div_width = div_width; > + ddrclk->ddr_flag = ddr_flag; > + > + clk = clk_register(NULL, &ddrclk->hw); > + if (IS_ERR(clk)) { > + pr_err("%s: could not register ddrclk %s\n", __func__, name); > + kfree(ddrclk); > + return NULL; > + } > + > + return clk; > +} > diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c > index 1f1c74f..99baa5d 100644 > --- a/drivers/clk/rockchip/clk.c > +++ b/drivers/clk/rockchip/clk.c > @@ -484,6 +484,15 @@ void __init rockchip_clk_register_branches( > list->gate_offset, list->gate_shift, > list->gate_flags, flags, &ctx->lock); > break; > + case branch_ddrc: > + clk = rockchip_clk_register_ddrclk( > + list->name, list->flags, > + list->parent_names, list->num_parents, > + list->muxdiv_offset, list->mux_shift, > + list->mux_width, list->div_shift, > + list->div_width, list->div_flags, > + ctx->reg_base, &ctx->lock); > + break; > } > > /* none of the cases above matched */ > diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h > index 3747de5..d6c58d0 100644 > --- a/drivers/clk/rockchip/clk.h > +++ b/drivers/clk/rockchip/clk.h > @@ -281,6 +281,22 @@ struct clk *rockchip_clk_register_mmc(const char *name, > const char *const *parent_names, u8 num_parents, > void __iomem *reg, int shift); > > +/* > + * for COMPOSITE_DDRCLK div_flag, > + * there may have serval ways to set ddr clock, use > + * this flag to distinguish them. > + * ROCKCHIP_DDRCLK_SIP: use SIP call to bl31 to change ddrclk rate. > + */ > +#define ROCKCHIP_DDRCLK_SIP 0x01 > + > +struct clk *rockchip_clk_register_ddrclk(const char *name, int flags, > + const char *const *parent_names, > + u8 num_parents, int mux_offset, > + int mux_shift, int mux_width, > + int div_shift, int div_width, > + int ddr_flags, void __iomem *reg_base, > + spinlock_t *lock); > + > #define ROCKCHIP_INVERTER_HIWORD_MASK BIT(0) > > struct clk *rockchip_clk_register_inverter(const char *name, > @@ -299,6 +315,7 @@ enum rockchip_clk_branch_type { > branch_mmc, > branch_inverter, > branch_factor, > + branch_ddrc, > }; > > struct rockchip_clk_branch { > @@ -488,6 +505,24 @@ struct rockchip_clk_branch { > .child = ch, \ > } > > +#define COMPOSITE_DDRCLK(_id, cname, pnames, f, mo, ms, mw, \ > + ds, dw, df) \ > + { \ > + .id = _id, \ > + .branch_type = branch_ddrc, \ > + .name = cname, \ > + .parent_names = pnames, \ > + .num_parents = ARRAY_SIZE(pnames), \ > + .flags = f, \ > + .muxdiv_offset = mo, \ > + .mux_shift = ms, \ > + .mux_width = mw, \ > + .div_shift = ds, \ > + .div_width = dw, \ > + .div_flags = df, \ > + .gate_offset = -1, \ > + } > + > #define MUX(_id, cname, pnames, f, o, s, w, mf) \ > { \ > .id = _id, \ > diff --git a/include/soc/rockchip/rockchip_sip.h > b/include/soc/rockchip/rockchip_sip.h new file mode 100644 > index 0000000..7e28092 > --- /dev/null > +++ b/include/soc/rockchip/rockchip_sip.h > @@ -0,0 +1,27 @@ > +/* > + * Copyright (c) 2016, Fuzhou Rockchip Electronics Co., Ltd > + * Author: Lin Huang > + * > + * This program is free software; you can redistribute it and/or modify it > + * under the terms and conditions of the GNU General Public License, > + * version 2, as published by the Free Software Foundation. > + * > + * This program is distributed in the hope it will be useful, but WITHOUT > + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or > + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License > for + * more details. > + */ > +#ifndef __SOC_ROCKCHIP_SIP_H > +#define __SOC_ROCKCHIP_SIP_H > + > +#define ROCKCHIP_SIP_DRAM_FREQ 0x82000008 > +#define ROCKCHIP_SIP_CONFIG_DRAM_INIT 0x00 > +#define ROCKCHIP_SIP_CONFIG_DRAM_SET_RATE 0x01 > +#define ROCKCHIP_SIP_CONFIG_DRAM_ROUND_RATE 0x02 > +#define ROCKCHIP_SIP_CONFIG_DRAM_SET_AT_SR 0x03 > +#define ROCKCHIP_SIP_CONFIG_DRAM_GET_BW 0x04 > +#define ROCKCHIP_SIP_CONFIG_DRAM_GET_RATE 0x05 > +#define ROCKCHIP_SIP_CONFIG_DRAM_CLR_IRQ 0x06 > +#define ROCKCHIP_SIP_CONFIG_DRAM_SET_PARAM 0x07 > + > +#endif From mboxrd@z Thu Jan 1 00:00:00 1970 From: Heiko =?ISO-8859-1?Q?St=FCbner?= Subject: Re: [PATCH v7 1/8] clk: rockchip: add new clock-type for the ddrclk Date: Thu, 01 Sep 2016 11:34:50 +0200 Message-ID: <2457390.MqltFPe7p9@diego> References: <1471836984-6316-1-git-send-email-hl@rock-chips.com> <1471836984-6316-2-git-send-email-hl@rock-chips.com> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: In-Reply-To: <1471836984-6316-2-git-send-email-hl@rock-chips.com> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" To: Lin Huang Cc: tixy@linaro.org, mark.rutland@arm.com, dbasehore@chromium.org, cw00.choi@samsung.com, mturquette@baylibre.com, typ@rock-chips.com, sboyd@codeaurora.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, dianders@chromium.org, linux-rockchip@lists.infradead.org, kyungmin.park@samsung.com, myungjoo.ham@samsung.com, sudeep.holla@arm.com, linux-pm@vger.kernel.org, linux-arm-kernel@lists.infradead.org List-Id: linux-pm@vger.kernel.org QW0gTW9udGFnLCAyMi4gQXVndXN0IDIwMTYsIDExOjM2OjE3IHNjaHJpZWIgTGluIEh1YW5nOgo+ IE9uIG5ldyByb2NrY2hpcCBwbGF0Zm9ybShyazMzOTkgZXRjKSwgdGhlcmUgaGF2ZSBkY2YgY29u dHJvbGxlciB0bwo+IGRvIGRkciBmcmVxdWVuY3kgc2NhbGluZywgYW5kIHRoaXMgY29udHJvbGxl ciB3aWxsIGltcGxlbWVudCBpbgo+IGFybS10cnVzdC1maXJtd2FyZS4gV2UgYWRkIGEgc3BlY2lh bCBjbG9jay10eXBlIHRvIGhhbmRsZSB0aGF0Lgo+IAo+IFNpZ25lZC1vZmYtYnk6IExpbiBIdWFu ZyA8aGxAcm9jay1jaGlwcy5jb20+CgpBcHBsaWVkIHdpdGggc29tZSBjaGFuZ2VzOgotIHNwbGl0 IHRoZSBzaXAgaGVhZGVyIGludG8gYSBzZXBhcmF0ZSBwYXRjaCBbMF0sIGFzIHdlJ2xsIG5lZWQg dGhlCiAgZGV2ZnJlcSBwYXJ0IHRvIGFsc28gaGF2ZSBhY2Nlc3MgdG8gdGhhdAotIHJld29yZCB0 aGUgY29tbWl0IG1lc3NhZ2UgWzFdIHRvIGhhdmUgc29tZSBtb3JlIGRldGFpbHMgb24gd2hhdAog IHdlIHdhbnQgdG8gYWNjb21wbGlzaCBoZXJlCi0gZHJvcCB0aGUgTk9fQ0FDSEUgZmxhZyBhcyBw ZXIgb3VyIGNoYXQsIGFzIHdlIG5vdyBhbHNvIGhhdmUgdGhlCiAgcm91bmQtcmF0ZSB0YWxraW5n IHRvIHRoZSBBVEYsIHNvIHRoZSBjYWNoZWQgdmFsdWUgc2hvdWxkIGFjdHVhbGwgbWF0Y2gKCgpb MF0gaHR0cHM6Ly9naXQua2VybmVsLm9yZy9jZ2l0L2xpbnV4L2tlcm5lbC9naXQvbW1pbmQvbGlu dXgtcm9ja2NoaXAuZ2l0L2NvbW1pdC8/aWQ9OTdkZDgyNjgyZjFhNjE3NDY5OGZiZWExNDlhMDRi NGNhYmM1OGM0ZgpbMV0gaHR0cHM6Ly9naXQua2VybmVsLm9yZy9jZ2l0L2xpbnV4L2tlcm5lbC9n aXQvbW1pbmQvbGludXgtcm9ja2NoaXAuZ2l0L2NvbW1pdC8/aWQ9YTRmMTgyYmY4MWYxOGY5MWYx YWVmNjI4OWZjZGZhNmEyYWM1MWI5OQoKCgo+IC0tLQo+IENoYW5nZXMgaW4gdjc6Cj4gLSBhZGQg cm9ja2NoaXBfZGRyY2xrX3NpcF9vcHMgc28gd2UgY2FuIGRpc3Rpbmd1aXNoIG90aGVyIGRkciBj bG9jayBvcGVyYXRlCj4gLSBhZGQgUk9DS0NISVBfU0lQX0NPTkZJR18qIGluIHJvY2tjaGlwX3Np cC5oIGdpdmUgY29uc3RhbnRzIGEgc3BlY2lmaWMgbmFtZQo+IAo+IENoYW5nZXMgaW4gdjY6Cj4g LSBub25lCj4gCj4gQ2hhbmdlcyBpbiB2NToKPiAtIGRlbGV0ZSB1bnVzZSBtdXhfZmxhZwo+IC0g dXNlIGRpdl9mbGFnIHRvIGRpc3Rpbmd1aXNoIHNpcCBjYWxsIGFuZCBvdGhlciBvcGVyYXRlCj4g Cj4gQ2hhbmdlcyBpbiB2NDoKPiAtIHVzZSBhcm1fc21jY2Nfc21jKCkgdG8gc2V0L3JlYWQgZGRy IHJhdGUKPiAKPiBDaGFuZ2VzIGluIHYzOgo+IC0gdXNlIHNpcCBjYWxsIHRvIHNldC9yZWFkIGRk ciByYXRlCj4gCj4gQ2hhbmdlcyBpbiB2MjoKPiAtIHVzZSBHRU5NQVNLIGluc3RlYWQgdmFsX21h c2sKPiAtIHVzZSBkaXZpZGVyX3JlY2FsY19yYXRlKCkgaW5zdGVhZCBESVZfUk9VTkRfVVBfVUxM Cj4gLSBjbGVhbnVwIGNvZGUKPiAKPiBDaGFuZ2VzIGluIHYxOgo+IC0gbm9uZQo+IAo+ICBkcml2 ZXJzL2Nsay9yb2NrY2hpcC9NYWtlZmlsZSAgICAgICB8ICAgMSArCj4gIGRyaXZlcnMvY2xrL3Jv Y2tjaGlwL2Nsay1kZHIuYyAgICAgIHwgMTU3Cj4gKysrKysrKysrKysrKysrKysrKysrKysrKysr KysrKysrKysrIGRyaXZlcnMvY2xrL3JvY2tjaGlwL2Nsay5jICAgICAgICAgIHwgCj4gIDkgKysr Cj4gIGRyaXZlcnMvY2xrL3JvY2tjaGlwL2Nsay5oICAgICAgICAgIHwgIDM1ICsrKysrKysrCj4g IGluY2x1ZGUvc29jL3JvY2tjaGlwL3JvY2tjaGlwX3NpcC5oIHwgIDI3ICsrKysrKysKPiAgNSBm aWxlcyBjaGFuZ2VkLCAyMjkgaW5zZXJ0aW9ucygrKQo+ICBjcmVhdGUgbW9kZSAxMDA2NDQgZHJp dmVycy9jbGsvcm9ja2NoaXAvY2xrLWRkci5jCj4gIGNyZWF0ZSBtb2RlIDEwMDY0NCBpbmNsdWRl L3NvYy9yb2NrY2hpcC9yb2NrY2hpcF9zaXAuaAo+IAo+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2Ns ay9yb2NrY2hpcC9NYWtlZmlsZSBiL2RyaXZlcnMvY2xrL3JvY2tjaGlwL01ha2VmaWxlCj4gaW5k ZXggZjQ3YTJmYS4uYjVmMmM4ZSAxMDA2NDQKPiAtLS0gYS9kcml2ZXJzL2Nsay9yb2NrY2hpcC9N YWtlZmlsZQo+ICsrKyBiL2RyaXZlcnMvY2xrL3JvY2tjaGlwL01ha2VmaWxlCj4gQEAgLTgsNiAr OCw3IEBAIG9iai15CSs9IGNsay1wbGwubwo+ICBvYmoteQkrPSBjbGstY3B1Lm8KPiAgb2JqLXkJ Kz0gY2xrLWludmVydGVyLm8KPiAgb2JqLXkJKz0gY2xrLW1tYy1waGFzZS5vCj4gK29iai15CSs9 IGNsay1kZHIubwo+ICBvYmotJChDT05GSUdfUkVTRVRfQ09OVFJPTExFUikJKz0gc29mdHJzdC5v Cj4gCj4gIG9iai15CSs9IGNsay1yazMwMzYubwo+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2Nsay9y b2NrY2hpcC9jbGstZGRyLmMgYi9kcml2ZXJzL2Nsay9yb2NrY2hpcC9jbGstZGRyLmMKPiBuZXcg ZmlsZSBtb2RlIDEwMDY0NAo+IGluZGV4IDAwMDAwMDAuLjIyNGUwN2UKPiAtLS0gL2Rldi9udWxs Cj4gKysrIGIvZHJpdmVycy9jbGsvcm9ja2NoaXAvY2xrLWRkci5jCj4gQEAgLTAsMCArMSwxNTcg QEAKPiArLyoKPiArICogQ29weXJpZ2h0IChjKSAyMDE2IFJvY2tjaGlwIEVsZWN0cm9uaWNzIENv LiBMdGQuCj4gKyAqIEF1dGhvcjogTGluIEh1YW5nIDxobEByb2NrLWNoaXBzLmNvbT4KPiArICoK PiArICogVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRl IGl0IGFuZC9vciBtb2RpZnkKPiArICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2Vu ZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkKPiArICogdGhlIEZyZWUgU29mdHdh cmUgRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24gMiBvZiB0aGUgTGljZW5zZSwgb3IKPiArICog KGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KPiArICoKPiArICogVGhpcyBwcm9n cmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCj4g KyAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdh cnJhbnR5IG9mCj4gKyAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VM QVIgUFVSUE9TRS4gIFNlZSB0aGUKPiArICogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9y IG1vcmUgZGV0YWlscy4KPiArICovCj4gKwo+ICsjaW5jbHVkZSA8bGludXgvYXJtLXNtY2NjLmg+ Cj4gKyNpbmNsdWRlIDxsaW51eC9jbGsuaD4KPiArI2luY2x1ZGUgPGxpbnV4L2Nsay1wcm92aWRl ci5oPgo+ICsjaW5jbHVkZSA8bGludXgvaW8uaD4KPiArI2luY2x1ZGUgPGxpbnV4L29mLmg+Cj4g KyNpbmNsdWRlIDxsaW51eC9zbGFiLmg+Cj4gKyNpbmNsdWRlIDxzb2Mvcm9ja2NoaXAvcm9ja2No aXBfc2lwLmg+Cj4gKwo+ICsjaW5jbHVkZSAiY2xrLmgiCj4gKwo+ICtzdHJ1Y3Qgcm9ja2NoaXBf ZGRyY2xrIHsKPiArCXN0cnVjdCBjbGtfaHcJaHc7Cj4gKwl2b2lkIF9faW9tZW0JKnJlZ19iYXNl Owo+ICsJaW50CQltdXhfb2Zmc2V0Owo+ICsJaW50CQltdXhfc2hpZnQ7Cj4gKwlpbnQJCW11eF93 aWR0aDsKPiArCWludAkJZGl2X3NoaWZ0Owo+ICsJaW50CQlkaXZfd2lkdGg7Cj4gKwlpbnQJCWRk cl9mbGFnOwo+ICsJc3BpbmxvY2tfdAkqbG9jazsKPiArfTsKPiArCj4gKyNkZWZpbmUgdG9fcm9j a2NoaXBfZGRyY2xrX2h3KGh3KSBjb250YWluZXJfb2YoaHcsIHN0cnVjdCByb2NrY2hpcF9kZHJj bGssCj4gaHcpICsKPiArc3RhdGljIGludCByb2NrY2hpcF9kZHJjbGtfc2lwX3NldF9yYXRlKHN0 cnVjdCBjbGtfaHcgKmh3LCB1bnNpZ25lZCBsb25nCj4gZHJhdGUsICsJCQkJCXVuc2lnbmVkIGxv bmcgcHJhdGUpCj4gK3sKPiArCXN0cnVjdCByb2NrY2hpcF9kZHJjbGsgKmRkcmNsayA9IHRvX3Jv Y2tjaGlwX2RkcmNsa19odyhodyk7Cj4gKwl1bnNpZ25lZCBsb25nIGZsYWdzOwo+ICsJc3RydWN0 IGFybV9zbWNjY19yZXMgcmVzOwo+ICsKPiArCXNwaW5fbG9ja19pcnFzYXZlKGRkcmNsay0+bG9j aywgZmxhZ3MpOwo+ICsJYXJtX3NtY2NjX3NtYyhST0NLQ0hJUF9TSVBfRFJBTV9GUkVRLCBkcmF0 ZSwgMCwKPiArCQkgICAgICBST0NLQ0hJUF9TSVBfQ09ORklHX0RSQU1fU0VUX1JBVEUsCj4gKwkJ ICAgICAgMCwgMCwgMCwgMCwgJnJlcyk7Cj4gKwlzcGluX3VubG9ja19pcnFyZXN0b3JlKGRkcmNs ay0+bG9jaywgZmxhZ3MpOwo+ICsKPiArCXJldHVybiByZXMuYTA7Cj4gK30KPiArCj4gK3N0YXRp YyB1bnNpZ25lZCBsb25nCj4gK3JvY2tjaGlwX2RkcmNsa19zaXBfcmVjYWxjX3JhdGUoc3RydWN0 IGNsa19odyAqaHcsCj4gKwkJCQl1bnNpZ25lZCBsb25nIHBhcmVudF9yYXRlKQo+ICt7Cj4gKwlz dHJ1Y3QgYXJtX3NtY2NjX3JlcyByZXM7Cj4gKwo+ICsJYXJtX3NtY2NjX3NtYyhST0NLQ0hJUF9T SVBfRFJBTV9GUkVRLCAwLCAwLAo+ICsJCSAgICAgIFJPQ0tDSElQX1NJUF9DT05GSUdfRFJBTV9H RVRfUkFURSwKPiArCQkgICAgICAwLCAwLCAwLCAwLCAmcmVzKTsKPiArCj4gKwlyZXR1cm4gcmVz LmEwOwo+ICt9Cj4gKwo+ICtzdGF0aWMgbG9uZyByb2NrY2hpcF9kZHJjbGtfc2lwX3JvdW5kX3Jh dGUoc3RydWN0IGNsa19odyAqaHcsCj4gKwkJCQkJICAgdW5zaWduZWQgbG9uZyByYXRlLAo+ICsJ CQkJCSAgIHVuc2lnbmVkIGxvbmcgKnByYXRlKQo+ICt7Cj4gKwlzdHJ1Y3QgYXJtX3NtY2NjX3Jl cyByZXM7Cj4gKwo+ICsJYXJtX3NtY2NjX3NtYyhST0NLQ0hJUF9TSVBfRFJBTV9GUkVRLCByYXRl LCAwLAo+ICsJCSAgICAgIFJPQ0tDSElQX1NJUF9DT05GSUdfRFJBTV9ST1VORF9SQVRFLAo+ICsJ CSAgICAgIDAsIDAsIDAsIDAsICZyZXMpOwo+ICsKPiArCXJldHVybiByZXMuYTA7Cj4gK30KPiAr Cj4gK3N0YXRpYyB1OCByb2NrY2hpcF9kZHJjbGtfZ2V0X3BhcmVudChzdHJ1Y3QgY2xrX2h3ICpo dykKPiArewo+ICsJc3RydWN0IHJvY2tjaGlwX2RkcmNsayAqZGRyY2xrID0gdG9fcm9ja2NoaXBf ZGRyY2xrX2h3KGh3KTsKPiArCWludCBudW1fcGFyZW50cyA9IGNsa19od19nZXRfbnVtX3BhcmVu dHMoaHcpOwo+ICsJdTMyIHZhbDsKPiArCj4gKwl2YWwgPSBjbGtfcmVhZGwoZGRyY2xrLT5yZWdf YmFzZSArCj4gKwkJCWRkcmNsay0+bXV4X29mZnNldCkgPj4gZGRyY2xrLT5tdXhfc2hpZnQ7Cj4g Kwl2YWwgJj0gR0VOTUFTSyhkZHJjbGstPm11eF93aWR0aCAtIDEsIDApOwo+ICsKPiArCWlmICh2 YWwgPj0gbnVtX3BhcmVudHMpCj4gKwkJcmV0dXJuIC1FSU5WQUw7Cj4gKwo+ICsJcmV0dXJuIHZh bDsKPiArfQo+ICsKPiArc3RhdGljIGNvbnN0IHN0cnVjdCBjbGtfb3BzIHJvY2tjaGlwX2RkcmNs a19zaXBfb3BzID0gewo+ICsJLnJlY2FsY19yYXRlID0gcm9ja2NoaXBfZGRyY2xrX3NpcF9yZWNh bGNfcmF0ZSwKPiArCS5zZXRfcmF0ZSA9IHJvY2tjaGlwX2RkcmNsa19zaXBfc2V0X3JhdGUsCj4g Kwkucm91bmRfcmF0ZSA9IHJvY2tjaGlwX2RkcmNsa19zaXBfcm91bmRfcmF0ZSwKPiArCS5nZXRf cGFyZW50ID0gcm9ja2NoaXBfZGRyY2xrX2dldF9wYXJlbnQsCj4gK307Cj4gKwo+ICtzdHJ1Y3Qg Y2xrICpyb2NrY2hpcF9jbGtfcmVnaXN0ZXJfZGRyY2xrKGNvbnN0IGNoYXIgKm5hbWUsIGludCBm bGFncywKPiArCQkJCQkgY29uc3QgY2hhciAqY29uc3QgKnBhcmVudF9uYW1lcywKPiArCQkJCQkg dTggbnVtX3BhcmVudHMsIGludCBtdXhfb2Zmc2V0LAo+ICsJCQkJCSBpbnQgbXV4X3NoaWZ0LCBp bnQgbXV4X3dpZHRoLAo+ICsJCQkJCSBpbnQgZGl2X3NoaWZ0LCBpbnQgZGl2X3dpZHRoLAo+ICsJ CQkJCSBpbnQgZGRyX2ZsYWcsIHZvaWQgX19pb21lbSAqcmVnX2Jhc2UsCj4gKwkJCQkJIHNwaW5s b2NrX3QgKmxvY2spCj4gK3sKPiArCXN0cnVjdCByb2NrY2hpcF9kZHJjbGsgKmRkcmNsazsKPiAr CXN0cnVjdCBjbGtfaW5pdF9kYXRhIGluaXQ7Cj4gKwlzdHJ1Y3QgY2xrICpjbGs7Cj4gKwo+ICsJ ZGRyY2xrID0ga3phbGxvYyhzaXplb2YoKmRkcmNsayksIEdGUF9LRVJORUwpOwo+ICsJaWYgKCFk ZHJjbGspCj4gKwkJcmV0dXJuIEVSUl9QVFIoLUVOT01FTSk7Cj4gKwo+ICsJaW5pdC5uYW1lID0g bmFtZTsKPiArCWluaXQucGFyZW50X25hbWVzID0gcGFyZW50X25hbWVzOwo+ICsJaW5pdC5udW1f cGFyZW50cyA9IG51bV9wYXJlbnRzOwo+ICsKPiArCWluaXQuZmxhZ3MgPSBmbGFnczsKPiArCWlu aXQuZmxhZ3MgfD0gQ0xLX1NFVF9SQVRFX05PX1JFUEFSRU5UOwo+ICsJaW5pdC5mbGFncyB8PSBD TEtfR0VUX1JBVEVfTk9DQUNIRTsKPiArCj4gKwlzd2l0Y2ggKGRkcl9mbGFnKSB7Cj4gKwljYXNl IFJPQ0tDSElQX0REUkNMS19TSVA6Cj4gKwkJaW5pdC5vcHMgPSAmcm9ja2NoaXBfZGRyY2xrX3Np cF9vcHM7Cj4gKwkJYnJlYWs7Cj4gKwlkZWZhdWx0Ogo+ICsJCXByX2VycigiJXM6IHVuc3VwcG9y dGVkIGRkcmNsayB0eXBlICVkXG4iLCBfX2Z1bmNfXywgZGRyX2ZsYWcpOwo+ICsJCWtmcmVlKGRk cmNsayk7Cj4gKwkJcmV0dXJuIEVSUl9QVFIoLUVJTlZBTCk7Cj4gKwl9Cj4gKwo+ICsJZGRyY2xr LT5yZWdfYmFzZSA9IHJlZ19iYXNlOwo+ICsJZGRyY2xrLT5sb2NrID0gbG9jazsKPiArCWRkcmNs ay0+aHcuaW5pdCA9ICZpbml0Owo+ICsJZGRyY2xrLT5tdXhfb2Zmc2V0ID0gbXV4X29mZnNldDsK PiArCWRkcmNsay0+bXV4X3NoaWZ0ID0gbXV4X3NoaWZ0Owo+ICsJZGRyY2xrLT5tdXhfd2lkdGgg PSBtdXhfd2lkdGg7Cj4gKwlkZHJjbGstPmRpdl9zaGlmdCA9IGRpdl9zaGlmdDsKPiArCWRkcmNs ay0+ZGl2X3dpZHRoID0gZGl2X3dpZHRoOwo+ICsJZGRyY2xrLT5kZHJfZmxhZyA9IGRkcl9mbGFn Owo+ICsKPiArCWNsayA9IGNsa19yZWdpc3RlcihOVUxMLCAmZGRyY2xrLT5odyk7Cj4gKwlpZiAo SVNfRVJSKGNsaykpIHsKPiArCQlwcl9lcnIoIiVzOiBjb3VsZCBub3QgcmVnaXN0ZXIgZGRyY2xr ICVzXG4iLCBfX2Z1bmNfXywJbmFtZSk7Cj4gKwkJa2ZyZWUoZGRyY2xrKTsKPiArCQlyZXR1cm4g TlVMTDsKPiArCX0KPiArCj4gKwlyZXR1cm4gY2xrOwo+ICt9Cj4gZGlmZiAtLWdpdCBhL2RyaXZl cnMvY2xrL3JvY2tjaGlwL2Nsay5jIGIvZHJpdmVycy9jbGsvcm9ja2NoaXAvY2xrLmMKPiBpbmRl eCAxZjFjNzRmLi45OWJhYTVkIDEwMDY0NAo+IC0tLSBhL2RyaXZlcnMvY2xrL3JvY2tjaGlwL2Ns ay5jCj4gKysrIGIvZHJpdmVycy9jbGsvcm9ja2NoaXAvY2xrLmMKPiBAQCAtNDg0LDYgKzQ4NCwx NSBAQCB2b2lkIF9faW5pdCByb2NrY2hpcF9jbGtfcmVnaXN0ZXJfYnJhbmNoZXMoCj4gIAkJCQls aXN0LT5nYXRlX29mZnNldCwgbGlzdC0+Z2F0ZV9zaGlmdCwKPiAgCQkJCWxpc3QtPmdhdGVfZmxh Z3MsIGZsYWdzLCAmY3R4LT5sb2NrKTsKPiAgCQkJYnJlYWs7Cj4gKwkJY2FzZSBicmFuY2hfZGRy YzoKPiArCQkJY2xrID0gcm9ja2NoaXBfY2xrX3JlZ2lzdGVyX2RkcmNsaygKPiArCQkJCWxpc3Qt Pm5hbWUsIGxpc3QtPmZsYWdzLAo+ICsJCQkJbGlzdC0+cGFyZW50X25hbWVzLCBsaXN0LT5udW1f cGFyZW50cywKPiArCQkJCWxpc3QtPm11eGRpdl9vZmZzZXQsIGxpc3QtPm11eF9zaGlmdCwKPiAr CQkJCWxpc3QtPm11eF93aWR0aCwgbGlzdC0+ZGl2X3NoaWZ0LAo+ICsJCQkJbGlzdC0+ZGl2X3dp ZHRoLCBsaXN0LT5kaXZfZmxhZ3MsCj4gKwkJCQljdHgtPnJlZ19iYXNlLCAmY3R4LT5sb2NrKTsK PiArCQkJYnJlYWs7Cj4gIAkJfQo+IAo+ICAJCS8qIG5vbmUgb2YgdGhlIGNhc2VzIGFib3ZlIG1h dGNoZWQgKi8KPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9jbGsvcm9ja2NoaXAvY2xrLmggYi9kcml2 ZXJzL2Nsay9yb2NrY2hpcC9jbGsuaAo+IGluZGV4IDM3NDdkZTUuLmQ2YzU4ZDAgMTAwNjQ0Cj4g LS0tIGEvZHJpdmVycy9jbGsvcm9ja2NoaXAvY2xrLmgKPiArKysgYi9kcml2ZXJzL2Nsay9yb2Nr Y2hpcC9jbGsuaAo+IEBAIC0yODEsNiArMjgxLDIyIEBAIHN0cnVjdCBjbGsgKnJvY2tjaGlwX2Ns a19yZWdpc3Rlcl9tbWMoY29uc3QgY2hhciAqbmFtZSwKPiBjb25zdCBjaGFyICpjb25zdCAqcGFy ZW50X25hbWVzLCB1OCBudW1fcGFyZW50cywKPiAgCQkJCXZvaWQgX19pb21lbSAqcmVnLCBpbnQg c2hpZnQpOwo+IAo+ICsvKgo+ICsgKiBmb3IgQ09NUE9TSVRFX0REUkNMSyBkaXZfZmxhZywKPiAr ICogdGhlcmUgbWF5IGhhdmUgc2VydmFsIHdheXMgdG8gc2V0IGRkciBjbG9jaywgdXNlCj4gKyAq IHRoaXMgZmxhZyB0byBkaXN0aW5ndWlzaCB0aGVtLgo+ICsgKiBST0NLQ0hJUF9ERFJDTEtfU0lQ OiB1c2UgU0lQIGNhbGwgdG8gYmwzMSB0byBjaGFuZ2UgZGRyY2xrIHJhdGUuCj4gKyAqLwo+ICsj ZGVmaW5lIFJPQ0tDSElQX0REUkNMS19TSVAJCTB4MDEKPiArCj4gK3N0cnVjdCBjbGsgKnJvY2tj aGlwX2Nsa19yZWdpc3Rlcl9kZHJjbGsoY29uc3QgY2hhciAqbmFtZSwgaW50IGZsYWdzLAo+ICsJ CQkJCSBjb25zdCBjaGFyICpjb25zdCAqcGFyZW50X25hbWVzLAo+ICsJCQkJCSB1OCBudW1fcGFy ZW50cywgaW50IG11eF9vZmZzZXQsCj4gKwkJCQkJIGludCBtdXhfc2hpZnQsIGludCBtdXhfd2lk dGgsCj4gKwkJCQkJIGludCBkaXZfc2hpZnQsIGludCBkaXZfd2lkdGgsCj4gKwkJCQkJIGludCBk ZHJfZmxhZ3MsIHZvaWQgX19pb21lbSAqcmVnX2Jhc2UsCj4gKwkJCQkJIHNwaW5sb2NrX3QgKmxv Y2spOwo+ICsKPiAgI2RlZmluZSBST0NLQ0hJUF9JTlZFUlRFUl9ISVdPUkRfTUFTSwlCSVQoMCkK PiAKPiAgc3RydWN0IGNsayAqcm9ja2NoaXBfY2xrX3JlZ2lzdGVyX2ludmVydGVyKGNvbnN0IGNo YXIgKm5hbWUsCj4gQEAgLTI5OSw2ICszMTUsNyBAQCBlbnVtIHJvY2tjaGlwX2Nsa19icmFuY2hf dHlwZSB7Cj4gIAlicmFuY2hfbW1jLAo+ICAJYnJhbmNoX2ludmVydGVyLAo+ICAJYnJhbmNoX2Zh Y3RvciwKPiArCWJyYW5jaF9kZHJjLAo+ICB9Owo+IAo+ICBzdHJ1Y3Qgcm9ja2NoaXBfY2xrX2Jy YW5jaCB7Cj4gQEAgLTQ4OCw2ICs1MDUsMjQgQEAgc3RydWN0IHJvY2tjaGlwX2Nsa19icmFuY2gg ewo+ICAJCS5jaGlsZAkJPSBjaCwJCQkJXAo+ICAJfQo+IAo+ICsjZGVmaW5lIENPTVBPU0lURV9E RFJDTEsoX2lkLCBjbmFtZSwgcG5hbWVzLCBmLCBtbywgbXMsIG13LAlcCj4gKwkJCSBkcywgZHcs IGRmKQkJCQlcCj4gKwl7CQkJCQkJCVwKPiArCQkuaWQJCT0gX2lkLAkJCQlcCj4gKwkJLmJyYW5j aF90eXBlCT0gYnJhbmNoX2RkcmMsCQkJXAo+ICsJCS5uYW1lCQk9IGNuYW1lLAkJCVwKPiArCQku cGFyZW50X25hbWVzCT0gcG5hbWVzLAkJCVwKPiArCQkubnVtX3BhcmVudHMJPSBBUlJBWV9TSVpF KHBuYW1lcyksCQlcCj4gKwkJLmZsYWdzCQk9IGYsCQkJCVwKPiArCQkubXV4ZGl2X29mZnNldCAg PSBtbywgICAgICAgICAgICAgICAgICAgICAgICAgICBcCj4gKwkJLm11eF9zaGlmdCAgICAgID0g bXMsICAgICAgICAgICAgICAgICAgICAgICAgICAgXAo+ICsJCS5tdXhfd2lkdGggICAgICA9IG13 LCAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKPiArCQkuZGl2X3NoaWZ0ICAgICAgPSBkcywg ICAgICAgICAgICAgICAgICAgICAgICAgICBcCj4gKwkJLmRpdl93aWR0aCAgICAgID0gZHcsICAg ICAgICAgICAgICAgICAgICAgICAgICAgXAo+ICsJCS5kaXZfZmxhZ3MJPSBkZiwJCQkJXAo+ICsJ CS5nYXRlX29mZnNldCAgICA9IC0xLCAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKPiArCX0K PiArCj4gICNkZWZpbmUgTVVYKF9pZCwgY25hbWUsIHBuYW1lcywgZiwgbywgcywgdywgbWYpCQkJ XAo+ICAJewkJCQkJCQlcCj4gIAkJLmlkCQk9IF9pZCwJCQkJXAo+IGRpZmYgLS1naXQgYS9pbmNs dWRlL3NvYy9yb2NrY2hpcC9yb2NrY2hpcF9zaXAuaAo+IGIvaW5jbHVkZS9zb2Mvcm9ja2NoaXAv cm9ja2NoaXBfc2lwLmggbmV3IGZpbGUgbW9kZSAxMDA2NDQKPiBpbmRleCAwMDAwMDAwLi43ZTI4 MDkyCj4gLS0tIC9kZXYvbnVsbAo+ICsrKyBiL2luY2x1ZGUvc29jL3JvY2tjaGlwL3JvY2tjaGlw X3NpcC5oCj4gQEAgLTAsMCArMSwyNyBAQAo+ICsvKgo+ICsgKiBDb3B5cmlnaHQgKGMpIDIwMTYs IEZ1emhvdSBSb2NrY2hpcCBFbGVjdHJvbmljcyBDby4sIEx0ZAo+ICsgKiBBdXRob3I6IExpbiBI dWFuZyA8aGxAcm9jay1jaGlwcy5jb20+Cj4gKyAqCj4gKyAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVl IHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Cj4gKyAq IHVuZGVyIHRoZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGlj IExpY2Vuc2UsCj4gKyAqIHZlcnNpb24gMiwgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3 YXJlIEZvdW5kYXRpb24uCj4gKyAqCj4gKyAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBp biB0aGUgaG9wZSBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKPiArICogQU5ZIFdBUlJB TlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZ IG9yCj4gKyAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUg R2VuZXJhbCBQdWJsaWMgTGljZW5zZQo+IGZvciArICogbW9yZSBkZXRhaWxzLgo+ICsgKi8KPiAr I2lmbmRlZiBfX1NPQ19ST0NLQ0hJUF9TSVBfSAo+ICsjZGVmaW5lIF9fU09DX1JPQ0tDSElQX1NJ UF9ICj4gKwo+ICsjZGVmaW5lIFJPQ0tDSElQX1NJUF9EUkFNX0ZSRVEJCQkweDgyMDAwMDA4Cj4g KyNkZWZpbmUgUk9DS0NISVBfU0lQX0NPTkZJR19EUkFNX0lOSVQJCTB4MDAKPiArI2RlZmluZSBS T0NLQ0hJUF9TSVBfQ09ORklHX0RSQU1fU0VUX1JBVEUJMHgwMQo+ICsjZGVmaW5lIFJPQ0tDSElQ X1NJUF9DT05GSUdfRFJBTV9ST1VORF9SQVRFCTB4MDIKPiArI2RlZmluZSBST0NLQ0hJUF9TSVBf Q09ORklHX0RSQU1fU0VUX0FUX1NSCTB4MDMKPiArI2RlZmluZSBST0NLQ0hJUF9TSVBfQ09ORklH X0RSQU1fR0VUX0JXCQkweDA0Cj4gKyNkZWZpbmUgUk9DS0NISVBfU0lQX0NPTkZJR19EUkFNX0dF VF9SQVRFCTB4MDUKPiArI2RlZmluZSBST0NLQ0hJUF9TSVBfQ09ORklHX0RSQU1fQ0xSX0lSUQkw eDA2Cj4gKyNkZWZpbmUgUk9DS0NISVBfU0lQX0NPTkZJR19EUkFNX1NFVF9QQVJBTQkweDA3Cj4g Kwo+ICsjZW5kaWYKCl9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fCmRyaS1kZXZlbCBtYWlsaW5nIGxpc3QKZHJpLWRldmVsQGxpc3RzLmZyZWVkZXNrdG9wLm9y ZwpodHRwczovL2xpc3RzLmZyZWVkZXNrdG9wLm9yZy9tYWlsbWFuL2xpc3RpbmZvL2RyaS1kZXZl bAo= From mboxrd@z Thu Jan 1 00:00:00 1970 From: heiko@sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=) Date: Thu, 01 Sep 2016 11:34:50 +0200 Subject: [PATCH v7 1/8] clk: rockchip: add new clock-type for the ddrclk In-Reply-To: <1471836984-6316-2-git-send-email-hl@rock-chips.com> References: <1471836984-6316-1-git-send-email-hl@rock-chips.com> <1471836984-6316-2-git-send-email-hl@rock-chips.com> Message-ID: <2457390.MqltFPe7p9@diego> To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org Am Montag, 22. August 2016, 11:36:17 schrieb Lin Huang: > On new rockchip platform(rk3399 etc), there have dcf controller to > do ddr frequency scaling, and this controller will implement in > arm-trust-firmware. We add a special clock-type to handle that. > > Signed-off-by: Lin Huang Applied with some changes: - split the sip header into a separate patch [0], as we'll need the devfreq part to also have access to that - reword the commit message [1] to have some more details on what we want to accomplish here - drop the NO_CACHE flag as per our chat, as we now also have the round-rate talking to the ATF, so the cached value should actuall match [0] https://git.kernel.org/cgit/linux/kernel/git/mmind/linux-rockchip.git/commit/?id=97dd82682f1a6174698fbea149a04b4cabc58c4f [1] https://git.kernel.org/cgit/linux/kernel/git/mmind/linux-rockchip.git/commit/?id=a4f182bf81f18f91f1aef6289fcdfa6a2ac51b99 > --- > Changes in v7: > - add rockchip_ddrclk_sip_ops so we can distinguish other ddr clock operate > - add ROCKCHIP_SIP_CONFIG_* in rockchip_sip.h give constants a specific name > > Changes in v6: > - none > > Changes in v5: > - delete unuse mux_flag > - use div_flag to distinguish sip call and other operate > > Changes in v4: > - use arm_smccc_smc() to set/read ddr rate > > Changes in v3: > - use sip call to set/read ddr rate > > Changes in v2: > - use GENMASK instead val_mask > - use divider_recalc_rate() instead DIV_ROUND_UP_ULL > - cleanup code > > Changes in v1: > - none > > drivers/clk/rockchip/Makefile | 1 + > drivers/clk/rockchip/clk-ddr.c | 157 > ++++++++++++++++++++++++++++++++++++ drivers/clk/rockchip/clk.c | > 9 +++ > drivers/clk/rockchip/clk.h | 35 ++++++++ > include/soc/rockchip/rockchip_sip.h | 27 +++++++ > 5 files changed, 229 insertions(+) > create mode 100644 drivers/clk/rockchip/clk-ddr.c > create mode 100644 include/soc/rockchip/rockchip_sip.h > > diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile > index f47a2fa..b5f2c8e 100644 > --- a/drivers/clk/rockchip/Makefile > +++ b/drivers/clk/rockchip/Makefile > @@ -8,6 +8,7 @@ obj-y += clk-pll.o > obj-y += clk-cpu.o > obj-y += clk-inverter.o > obj-y += clk-mmc-phase.o > +obj-y += clk-ddr.o > obj-$(CONFIG_RESET_CONTROLLER) += softrst.o > > obj-y += clk-rk3036.o > diff --git a/drivers/clk/rockchip/clk-ddr.c b/drivers/clk/rockchip/clk-ddr.c > new file mode 100644 > index 0000000..224e07e > --- /dev/null > +++ b/drivers/clk/rockchip/clk-ddr.c > @@ -0,0 +1,157 @@ > +/* > + * Copyright (c) 2016 Rockchip Electronics Co. Ltd. > + * Author: Lin Huang > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License as published by > + * the Free Software Foundation; either version 2 of the License, or > + * (at your option) any later version. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include "clk.h" > + > +struct rockchip_ddrclk { > + struct clk_hw hw; > + void __iomem *reg_base; > + int mux_offset; > + int mux_shift; > + int mux_width; > + int div_shift; > + int div_width; > + int ddr_flag; > + spinlock_t *lock; > +}; > + > +#define to_rockchip_ddrclk_hw(hw) container_of(hw, struct rockchip_ddrclk, > hw) + > +static int rockchip_ddrclk_sip_set_rate(struct clk_hw *hw, unsigned long > drate, + unsigned long prate) > +{ > + struct rockchip_ddrclk *ddrclk = to_rockchip_ddrclk_hw(hw); > + unsigned long flags; > + struct arm_smccc_res res; > + > + spin_lock_irqsave(ddrclk->lock, flags); > + arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, drate, 0, > + ROCKCHIP_SIP_CONFIG_DRAM_SET_RATE, > + 0, 0, 0, 0, &res); > + spin_unlock_irqrestore(ddrclk->lock, flags); > + > + return res.a0; > +} > + > +static unsigned long > +rockchip_ddrclk_sip_recalc_rate(struct clk_hw *hw, > + unsigned long parent_rate) > +{ > + struct arm_smccc_res res; > + > + arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, 0, 0, > + ROCKCHIP_SIP_CONFIG_DRAM_GET_RATE, > + 0, 0, 0, 0, &res); > + > + return res.a0; > +} > + > +static long rockchip_ddrclk_sip_round_rate(struct clk_hw *hw, > + unsigned long rate, > + unsigned long *prate) > +{ > + struct arm_smccc_res res; > + > + arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, rate, 0, > + ROCKCHIP_SIP_CONFIG_DRAM_ROUND_RATE, > + 0, 0, 0, 0, &res); > + > + return res.a0; > +} > + > +static u8 rockchip_ddrclk_get_parent(struct clk_hw *hw) > +{ > + struct rockchip_ddrclk *ddrclk = to_rockchip_ddrclk_hw(hw); > + int num_parents = clk_hw_get_num_parents(hw); > + u32 val; > + > + val = clk_readl(ddrclk->reg_base + > + ddrclk->mux_offset) >> ddrclk->mux_shift; > + val &= GENMASK(ddrclk->mux_width - 1, 0); > + > + if (val >= num_parents) > + return -EINVAL; > + > + return val; > +} > + > +static const struct clk_ops rockchip_ddrclk_sip_ops = { > + .recalc_rate = rockchip_ddrclk_sip_recalc_rate, > + .set_rate = rockchip_ddrclk_sip_set_rate, > + .round_rate = rockchip_ddrclk_sip_round_rate, > + .get_parent = rockchip_ddrclk_get_parent, > +}; > + > +struct clk *rockchip_clk_register_ddrclk(const char *name, int flags, > + const char *const *parent_names, > + u8 num_parents, int mux_offset, > + int mux_shift, int mux_width, > + int div_shift, int div_width, > + int ddr_flag, void __iomem *reg_base, > + spinlock_t *lock) > +{ > + struct rockchip_ddrclk *ddrclk; > + struct clk_init_data init; > + struct clk *clk; > + > + ddrclk = kzalloc(sizeof(*ddrclk), GFP_KERNEL); > + if (!ddrclk) > + return ERR_PTR(-ENOMEM); > + > + init.name = name; > + init.parent_names = parent_names; > + init.num_parents = num_parents; > + > + init.flags = flags; > + init.flags |= CLK_SET_RATE_NO_REPARENT; > + init.flags |= CLK_GET_RATE_NOCACHE; > + > + switch (ddr_flag) { > + case ROCKCHIP_DDRCLK_SIP: > + init.ops = &rockchip_ddrclk_sip_ops; > + break; > + default: > + pr_err("%s: unsupported ddrclk type %d\n", __func__, ddr_flag); > + kfree(ddrclk); > + return ERR_PTR(-EINVAL); > + } > + > + ddrclk->reg_base = reg_base; > + ddrclk->lock = lock; > + ddrclk->hw.init = &init; > + ddrclk->mux_offset = mux_offset; > + ddrclk->mux_shift = mux_shift; > + ddrclk->mux_width = mux_width; > + ddrclk->div_shift = div_shift; > + ddrclk->div_width = div_width; > + ddrclk->ddr_flag = ddr_flag; > + > + clk = clk_register(NULL, &ddrclk->hw); > + if (IS_ERR(clk)) { > + pr_err("%s: could not register ddrclk %s\n", __func__, name); > + kfree(ddrclk); > + return NULL; > + } > + > + return clk; > +} > diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c > index 1f1c74f..99baa5d 100644 > --- a/drivers/clk/rockchip/clk.c > +++ b/drivers/clk/rockchip/clk.c > @@ -484,6 +484,15 @@ void __init rockchip_clk_register_branches( > list->gate_offset, list->gate_shift, > list->gate_flags, flags, &ctx->lock); > break; > + case branch_ddrc: > + clk = rockchip_clk_register_ddrclk( > + list->name, list->flags, > + list->parent_names, list->num_parents, > + list->muxdiv_offset, list->mux_shift, > + list->mux_width, list->div_shift, > + list->div_width, list->div_flags, > + ctx->reg_base, &ctx->lock); > + break; > } > > /* none of the cases above matched */ > diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h > index 3747de5..d6c58d0 100644 > --- a/drivers/clk/rockchip/clk.h > +++ b/drivers/clk/rockchip/clk.h > @@ -281,6 +281,22 @@ struct clk *rockchip_clk_register_mmc(const char *name, > const char *const *parent_names, u8 num_parents, > void __iomem *reg, int shift); > > +/* > + * for COMPOSITE_DDRCLK div_flag, > + * there may have serval ways to set ddr clock, use > + * this flag to distinguish them. > + * ROCKCHIP_DDRCLK_SIP: use SIP call to bl31 to change ddrclk rate. > + */ > +#define ROCKCHIP_DDRCLK_SIP 0x01 > + > +struct clk *rockchip_clk_register_ddrclk(const char *name, int flags, > + const char *const *parent_names, > + u8 num_parents, int mux_offset, > + int mux_shift, int mux_width, > + int div_shift, int div_width, > + int ddr_flags, void __iomem *reg_base, > + spinlock_t *lock); > + > #define ROCKCHIP_INVERTER_HIWORD_MASK BIT(0) > > struct clk *rockchip_clk_register_inverter(const char *name, > @@ -299,6 +315,7 @@ enum rockchip_clk_branch_type { > branch_mmc, > branch_inverter, > branch_factor, > + branch_ddrc, > }; > > struct rockchip_clk_branch { > @@ -488,6 +505,24 @@ struct rockchip_clk_branch { > .child = ch, \ > } > > +#define COMPOSITE_DDRCLK(_id, cname, pnames, f, mo, ms, mw, \ > + ds, dw, df) \ > + { \ > + .id = _id, \ > + .branch_type = branch_ddrc, \ > + .name = cname, \ > + .parent_names = pnames, \ > + .num_parents = ARRAY_SIZE(pnames), \ > + .flags = f, \ > + .muxdiv_offset = mo, \ > + .mux_shift = ms, \ > + .mux_width = mw, \ > + .div_shift = ds, \ > + .div_width = dw, \ > + .div_flags = df, \ > + .gate_offset = -1, \ > + } > + > #define MUX(_id, cname, pnames, f, o, s, w, mf) \ > { \ > .id = _id, \ > diff --git a/include/soc/rockchip/rockchip_sip.h > b/include/soc/rockchip/rockchip_sip.h new file mode 100644 > index 0000000..7e28092 > --- /dev/null > +++ b/include/soc/rockchip/rockchip_sip.h > @@ -0,0 +1,27 @@ > +/* > + * Copyright (c) 2016, Fuzhou Rockchip Electronics Co., Ltd > + * Author: Lin Huang > + * > + * This program is free software; you can redistribute it and/or modify it > + * under the terms and conditions of the GNU General Public License, > + * version 2, as published by the Free Software Foundation. > + * > + * This program is distributed in the hope it will be useful, but WITHOUT > + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or > + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License > for + * more details. > + */ > +#ifndef __SOC_ROCKCHIP_SIP_H > +#define __SOC_ROCKCHIP_SIP_H > + > +#define ROCKCHIP_SIP_DRAM_FREQ 0x82000008 > +#define ROCKCHIP_SIP_CONFIG_DRAM_INIT 0x00 > +#define ROCKCHIP_SIP_CONFIG_DRAM_SET_RATE 0x01 > +#define ROCKCHIP_SIP_CONFIG_DRAM_ROUND_RATE 0x02 > +#define ROCKCHIP_SIP_CONFIG_DRAM_SET_AT_SR 0x03 > +#define ROCKCHIP_SIP_CONFIG_DRAM_GET_BW 0x04 > +#define ROCKCHIP_SIP_CONFIG_DRAM_GET_RATE 0x05 > +#define ROCKCHIP_SIP_CONFIG_DRAM_CLR_IRQ 0x06 > +#define ROCKCHIP_SIP_CONFIG_DRAM_SET_PARAM 0x07 > + > +#endif